package tech.easyflow.agent.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.UUID;

/**
 * Agent 运行态生产化配置。
 */
@ConfigurationProperties(prefix = "easyflow.agent.runtime")
public class AgentRuntimeProperties {

    /**
     * Redis 热态 session 缓存 TTL。
     */
    private Duration sessionCacheTtl = Duration.ofHours(24);

    /**
     * 当前 Agent 运行实例 ID。
     */
    private String instanceId = defaultInstanceId();

    /**
     * Agent 运行路由 TTL。
     */
    private Duration routeTtl = Duration.ofHours(24);

    /**
     * Agent 运行命令 topic 前缀。
     */
    private String commandTopicPrefix = "easyflow:agent-runtime-command";

    /**
     * Agent 运行命令结果等待超时时间。
     */
    private Duration commandResultTimeout = Duration.ofSeconds(5);

    /**
     * Agent 运行命令结果缓存 TTL。
     */
    private Duration commandResultTtl = Duration.ofMinutes(5);

    /**
     * 当前进程启动代 ID。
     */
    private final String bootId = UUID.randomUUID().toString();

    /**
     * HITL pending 默认过期时间。
     */
    private Duration hitlPendingTimeout = Duration.ofMinutes(30);

    /**
     * 运行锁等待时间。
     */
    private Duration lockWaitTimeout = Duration.ofSeconds(2);

    /**
     * 运行锁租约时间。
     */
    private Duration lockLeaseTimeout = Duration.ofMinutes(5);

    /**
     * 运行锁续期间隔。
     */
    private Duration lockRenewInterval = Duration.ofMinutes(1);

    /**
     * Agent 异步工具任务 Redis 运行态 TTL。
     */
    private Duration asyncToolTaskTtl = Duration.ofHours(24);

    /**
     * 获取 Redis 热态 session 缓存 TTL。
     *
     * @return 缓存 TTL
     */
    public Duration getSessionCacheTtl() {
        return sessionCacheTtl;
    }

    /**
     * 设置 Redis 热态 session 缓存 TTL。
     *
     * @param sessionCacheTtl 缓存 TTL
     */
    public void setSessionCacheTtl(Duration sessionCacheTtl) {
        this.sessionCacheTtl = sessionCacheTtl == null ? Duration.ofHours(24) : sessionCacheTtl;
    }

    /**
     * 获取当前 Agent 运行实例 ID。
     *
     * @return 实例 ID
     */
    public String getInstanceId() {
        return instanceId;
    }

    /**
     * 设置当前 Agent 运行实例 ID。
     *
     * @param instanceId 实例 ID
     */
    public void setInstanceId(String instanceId) {
        this.instanceId = StringUtils.hasText(instanceId) ? instanceId.trim() : defaultInstanceId();
    }

    /**
     * 获取 Agent 运行路由 TTL。
     *
     * @return 路由 TTL
     */
    public Duration getRouteTtl() {
        return routeTtl;
    }

    /**
     * 设置 Agent 运行路由 TTL。
     *
     * @param routeTtl 路由 TTL
     */
    public void setRouteTtl(Duration routeTtl) {
        this.routeTtl = routeTtl == null ? Duration.ofHours(24) : routeTtl;
    }

    /**
     * 获取 Agent 运行命令 topic 前缀。
     *
     * @return 命令 topic 前缀
     */
    public String getCommandTopicPrefix() {
        return commandTopicPrefix;
    }

    /**
     * 设置 Agent 运行命令 topic 前缀。
     *
     * @param commandTopicPrefix 命令 topic 前缀
     */
    public void setCommandTopicPrefix(String commandTopicPrefix) {
        this.commandTopicPrefix = StringUtils.hasText(commandTopicPrefix)
                ? commandTopicPrefix.trim()
                : "easyflow:agent-runtime-command";
    }

    /**
     * 获取 Agent 运行命令结果等待超时时间。
     *
     * @return 等待超时时间
     */
    public Duration getCommandResultTimeout() {
        return commandResultTimeout;
    }

    /**
     * 设置 Agent 运行命令结果等待超时时间。
     *
     * @param commandResultTimeout 等待超时时间
     */
    public void setCommandResultTimeout(Duration commandResultTimeout) {
        this.commandResultTimeout = commandResultTimeout == null ? Duration.ofSeconds(5) : commandResultTimeout;
    }

    /**
     * 获取 Agent 运行命令结果缓存 TTL。
     *
     * @return 结果缓存 TTL
     */
    public Duration getCommandResultTtl() {
        return commandResultTtl;
    }

    /**
     * 设置 Agent 运行命令结果缓存 TTL。
     *
     * @param commandResultTtl 结果缓存 TTL
     */
    public void setCommandResultTtl(Duration commandResultTtl) {
        this.commandResultTtl = commandResultTtl == null ? Duration.ofMinutes(5) : commandResultTtl;
    }

    /**
     * 获取当前进程启动代 ID。
     *
     * @return 启动代 ID
     */
    public String getBootId() {
        return bootId;
    }

    /**
     * 获取 HITL pending 默认过期时间。
     *
     * @return 过期时间
     */
    public Duration getHitlPendingTimeout() {
        return hitlPendingTimeout;
    }

    /**
     * 设置 HITL pending 默认过期时间。
     *
     * @param hitlPendingTimeout 过期时间
     */
    public void setHitlPendingTimeout(Duration hitlPendingTimeout) {
        this.hitlPendingTimeout = hitlPendingTimeout == null ? Duration.ofMinutes(30) : hitlPendingTimeout;
    }

    /**
     * 获取运行锁等待时间。
     *
     * @return 等待时间
     */
    public Duration getLockWaitTimeout() {
        return lockWaitTimeout;
    }

    /**
     * 设置运行锁等待时间。
     *
     * @param lockWaitTimeout 等待时间
     */
    public void setLockWaitTimeout(Duration lockWaitTimeout) {
        this.lockWaitTimeout = lockWaitTimeout == null ? Duration.ofSeconds(2) : lockWaitTimeout;
    }

    /**
     * 获取运行锁租约时间。
     *
     * @return 租约时间
     */
    public Duration getLockLeaseTimeout() {
        return lockLeaseTimeout;
    }

    /**
     * 设置运行锁租约时间。
     *
     * @param lockLeaseTimeout 租约时间
     */
    public void setLockLeaseTimeout(Duration lockLeaseTimeout) {
        this.lockLeaseTimeout = lockLeaseTimeout == null ? Duration.ofMinutes(5) : lockLeaseTimeout;
    }

    /**
     * 获取运行锁续期间隔。
     *
     * @return 续期间隔
     */
    public Duration getLockRenewInterval() {
        return lockRenewInterval;
    }

    /**
     * 设置运行锁续期间隔。
     *
     * @param lockRenewInterval 续期间隔
     */
    public void setLockRenewInterval(Duration lockRenewInterval) {
        this.lockRenewInterval = lockRenewInterval == null ? Duration.ofMinutes(1) : lockRenewInterval;
    }

    /**
     * 获取 Agent 异步工具任务 Redis 运行态 TTL。
     *
     * @return 任务 TTL
     */
    public Duration getAsyncToolTaskTtl() {
        return asyncToolTaskTtl;
    }

    /**
     * 设置 Agent 异步工具任务 Redis 运行态 TTL。
     *
     * @param asyncToolTaskTtl 任务 TTL
     */
    public void setAsyncToolTaskTtl(Duration asyncToolTaskTtl) {
        this.asyncToolTaskTtl = asyncToolTaskTtl == null ? Duration.ofHours(24) : asyncToolTaskTtl;
    }

    private static String defaultInstanceId() {
        String envInstanceId = System.getenv("EASYFLOW_INSTANCE_ID");
        if (StringUtils.hasText(envInstanceId)) {
            return envInstanceId.trim();
        }
        String hostName = System.getenv("HOSTNAME");
        if (StringUtils.hasText(hostName)) {
            return hostName.trim();
        }
        return UUID.randomUUID().toString();
    }
}
