package com.agent.management.engine.hermes;

import com.agent.management.config.HermesProperties;
import com.agent.management.engine.SkillFileSyncer;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Component;

import java.nio.file.Path;

/**
 * Hermes 技能写时同步服务。
 *
 * <p>固定 HERMES_HOME 架构：Bridge 子进程启动时通过 --hermes-home 指向固定目录
 * （{@code hermes.bridge.home}，默认 ./data/hermes-home），Java 侧在技能发生
 * 新增/更新/删除/回滚时调用 {@link #syncAfterWrite()}，将 uploads/skills
 * 精确镜像到 {home}/skills，并通知 Bridge 清空技能索引缓存与 Agent 池，
 * 使 skill_view / skills_list 立即可见最新技能。</p>
 *
 * <p>同步失败仅记录日志，不阻断技能 CRUD 主流程。</p>
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class HermesSkillSyncService {

    private final HermesProperties hermesProperties;
    private final SkillFileSyncer skillFileSyncer;
    private final ObjectProvider<HermesBridgeClient> bridgeClientProvider;

    /**
     * 应用启动时做一次全量同步，保证固定 HERMES_HOME 与 uploads/skills 一致
     * （覆盖 Bridge 重启、上次关闭期间的离线改动等场景）。
     */
    @PostConstruct
    public void initialSync() {
        if (!hermesProperties.isEnabled()) {
            return;
        }
        try {
            int synced = skillFileSyncer.syncTo(skillsDir());
            log.info("[HermesSkillSync] 启动同步完成: {} 个 skill -> {}", synced, skillsDir());
        } catch (Exception e) {
            log.error("[HermesSkillSync] 启动同步失败（运行期写时同步仍会重试）: {}", e.getMessage(), e);
        }
    }

    /**
     * 技能写操作（新增/更新/删除/回滚/生成）后的同步入口。
     * 幂等：全量镜像同步 + Bridge 缓存失效。失败不抛异常。
     */
    public void syncAfterWrite() {
        if (!hermesProperties.isEnabled()) {
            return;
        }
        try {
            int synced = skillFileSyncer.syncTo(skillsDir());
            log.info("[HermesSkillSync] 写时同步完成: {} 个 skill", synced);
        } catch (Exception e) {
            log.warn("[HermesSkillSync] 写时同步失败: {}", e.getMessage(), e);
            return;
        }
        HermesBridgeClient client = bridgeClientProvider.getIfAvailable();
        if (client != null) {
            client.invalidateSkillsCache();
        }
    }

    /** 固定 HERMES_HOME 下的 skills 目录 */
    private Path skillsDir() {
        return hermesProperties.getBridge().getResolvedHome().resolve("skills");
    }
}
