package com.cameleer.server.app.license;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Read-side usage snapshot used by the /api/v1/admin/license/usage endpoint and license metrics.
 *
 * <p>Counts come straight from PostgreSQL row counts; compute aggregates SUM over
 * non-stopped deployments and read replica/cpu/memory from the
 * {@code deployed_config_snapshot.containerConfig} JSONB sub-object. Pre-RUNNING deployments
 * (STARTING with no snapshot yet) contribute defaults (1 replica, 0 cpu, 0 memory) until they
 * roll forward.</p>
 *
 * <p>{@code max_agents} is not in PG — the registry is in-memory; callers feed the live count
 * into {@link #agentCount(int)} which echoes it for assembly into the snapshot map.</p>
 */
@Component
public class LicenseUsageReader {

    private final JdbcTemplate jdbc;

    public LicenseUsageReader(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    public Map<String, Long> snapshot() {
        Map<String, Long> out = new LinkedHashMap<>();
        out.put("max_environments", count("environments"));
        out.put("max_apps", count("apps"));
        out.put("max_users", count("users"));
        out.put("max_outbound_connections", count("outbound_connections"));
        out.put("max_alert_rules", count("alert_rules"));
        Map<String, Long> compute = jdbc.queryForObject(
                "SELECT " +
                "  COALESCE(SUM(replicas * cpu_millis), 0) AS cpu, " +
                "  COALESCE(SUM(replicas * memory_mb), 0) AS mem, " +
                "  COALESCE(SUM(replicas), 0) AS reps " +
                "FROM ( " +
                "  SELECT " +
                "    COALESCE((d.deployed_config_snapshot->'containerConfig'->>'replicas')::int, 1) AS replicas, " +
                "    COALESCE((d.deployed_config_snapshot->'containerConfig'->>'cpuLimit')::int, 0) AS cpu_millis, " +
                "    COALESCE((d.deployed_config_snapshot->'containerConfig'->>'memoryLimitMb')::int, 0) AS memory_mb " +
                "  FROM deployments d " +
                "  WHERE d.status IN ('STARTING','RUNNING','DEGRADED','STOPPING') " +
                ") s",
                (rs, n) -> Map.of(
                        "max_total_cpu_millis", rs.getLong("cpu"),
                        "max_total_memory_mb", rs.getLong("mem"),
                        "max_total_replicas", rs.getLong("reps")
                ));
        out.putAll(compute);
        return out;
    }

    /** Echoes the live agent count fed in by the controller (registry is in-memory). */
    public long agentCount(int liveAgents) {
        return liveAgents;
    }

    private long count(String table) {
        return jdbc.queryForObject("SELECT COUNT(*) FROM " + table, Long.class);
    }
}
