package com.cameleer.server.core.license;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicReference;

public class LicenseGate {

    private static final Logger log = LoggerFactory.getLogger(LicenseGate.class);

    private static final class Snapshot {
        final LicenseInfo license;            // null when ABSENT or INVALID
        final String invalidReason;           // null unless INVALID
        Snapshot(LicenseInfo l, String r) { this.license = l; this.invalidReason = r; }
    }

    private final AtomicReference<Snapshot> snap = new AtomicReference<>(new Snapshot(null, null));

    public void load(LicenseInfo license) {
        snap.set(new Snapshot(license, null));
        log.info("License loaded: licenseId={}, tenantId={}, exp={}, gracePeriodDays={}",
                license.licenseId(), license.tenantId(), license.expiresAt(), license.gracePeriodDays());
    }

    public void markInvalid(String reason) {
        snap.set(new Snapshot(null, reason));
        log.error("License marked INVALID: {}", reason);
    }

    public void clear() {
        snap.set(new Snapshot(null, null));
        log.info("License cleared");
    }

    public LicenseInfo getCurrent() {
        return snap.get().license;
    }

    public String getInvalidReason() {
        return snap.get().invalidReason;
    }

    public LicenseState getState() {
        Snapshot s = snap.get();
        return LicenseStateMachine.classify(s.license, s.invalidReason);
    }

    /** Effective limits = defaults UNION license.limits, except in EXPIRED/ABSENT/INVALID where defaults win. */
    public LicenseLimits getEffectiveLimits() {
        Snapshot s = snap.get();
        LicenseState state = LicenseStateMachine.classify(s.license, s.invalidReason);
        if (state == LicenseState.ACTIVE || state == LicenseState.GRACE) {
            return LicenseLimits.mergeOverDefaults(s.license.limits());
        }
        return LicenseLimits.defaultsOnly();
    }

    public int getLimit(String key, int defaultValue) {
        try {
            return getEffectiveLimits().get(key);
        } catch (IllegalArgumentException e) {
            return defaultValue;
        }
    }
}
