package com.cameleer.server.core.agent;

import java.time.Instant;
import java.util.List;
import java.util.Map;

/**
 * Immutable record representing a registered agent's current state.
 * <p>
 * Stored in a {@link java.util.concurrent.ConcurrentHashMap} and atomically swapped
 * via {@code computeIfPresent} for thread-safe state transitions. Wither-style methods
 * return new instances with the specified field changed.
 *
 * @param instanceId       agent-provided persistent identifier
 * @param displayName      human-readable agent name
 * @param applicationId    application identifier (e.g., "order-service-prod")
 * @param environmentId    logical environment (e.g., "dev", "staging", "prod")
 * @param version          agent software version
 * @param routeIds         list of Camel route IDs managed by this agent
 * @param capabilities     agent-declared capabilities (free-form)
 * @param state            current lifecycle state
 * @param registeredAt     when the agent first registered (or re-registered)
 * @param lastHeartbeat    last heartbeat timestamp
 * @param staleTransitionTime when the agent transitioned to STALE (null if not STALE/DEAD)
 */
public record AgentInfo(
        String instanceId,
        String displayName,
        String applicationId,
        String environmentId,
        String version,
        List<String> routeIds,
        Map<String, Object> capabilities,
        AgentState state,
        Instant registeredAt,
        Instant lastHeartbeat,
        Instant staleTransitionTime
) {

    public AgentInfo withState(AgentState newState) {
        return new AgentInfo(instanceId, displayName, applicationId, environmentId, version, routeIds, capabilities,
                newState, registeredAt, lastHeartbeat, staleTransitionTime);
    }

    public AgentInfo withLastHeartbeat(Instant newLastHeartbeat) {
        return new AgentInfo(instanceId, displayName, applicationId, environmentId, version, routeIds, capabilities,
                state, registeredAt, newLastHeartbeat, staleTransitionTime);
    }

    public AgentInfo withRegisteredAt(Instant newRegisteredAt) {
        return new AgentInfo(instanceId, displayName, applicationId, environmentId, version, routeIds, capabilities,
                state, newRegisteredAt, lastHeartbeat, staleTransitionTime);
    }

    public AgentInfo withStaleTransitionTime(Instant newStaleTransitionTime) {
        return new AgentInfo(instanceId, displayName, applicationId, environmentId, version, routeIds, capabilities,
                state, registeredAt, lastHeartbeat, newStaleTransitionTime);
    }

    public AgentInfo withRouteIds(List<String> newRouteIds) {
        return new AgentInfo(instanceId, displayName, applicationId, environmentId, version, newRouteIds, capabilities,
                state, registeredAt, lastHeartbeat, staleTransitionTime);
    }

    public AgentInfo withCapabilities(Map<String, Object> newCapabilities) {
        return new AgentInfo(instanceId, displayName, applicationId, environmentId, version, routeIds, newCapabilities,
                state, registeredAt, lastHeartbeat, staleTransitionTime);
    }

    public AgentInfo withMetadata(String displayName, String applicationId, String environmentId,
                                   String version, List<String> routeIds, Map<String, Object> capabilities) {
        return new AgentInfo(instanceId, displayName, applicationId, environmentId, version, routeIds, capabilities,
                state, registeredAt, lastHeartbeat, staleTransitionTime);
    }
}
