package com.cameleer.license.minter;

import com.cameleer.server.core.license.LicenseInfo;
import com.cameleer.server.core.license.LicenseValidator;
import org.junit.jupiter.api.Test;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.time.Instant;
import java.util.Base64;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;

class LicenseMinterTest {

    @Test
    void roundTrip_validatorAcceptsMintedToken() throws Exception {
        KeyPair kp = KeyPairGenerator.getInstance("Ed25519").generateKeyPair();
        String publicB64 = Base64.getEncoder().encodeToString(kp.getPublic().getEncoded());

        LicenseInfo info = new LicenseInfo(
                UUID.randomUUID(), "acme", "ACME prod",
                Map.of("max_apps", 50, "max_agents", 100),
                Instant.now(), Instant.now().plusSeconds(86400), 7);

        String token = LicenseMinter.mint(info, kp.getPrivate());

        LicenseInfo parsed = new LicenseValidator(publicB64, "acme").validate(token);
        assertThat(parsed.licenseId()).isEqualTo(info.licenseId());
        assertThat(parsed.tenantId()).isEqualTo("acme");
        assertThat(parsed.limits().get("max_apps")).isEqualTo(50);
        assertThat(parsed.gracePeriodDays()).isEqualTo(7);
    }

    @Test
    void canonicalJson_isStableAcrossRuns() throws Exception {
        KeyPair kp = KeyPairGenerator.getInstance("Ed25519").generateKeyPair();
        UUID id = UUID.randomUUID();
        Instant now = Instant.parse("2026-04-25T10:00:00Z");
        Instant exp = Instant.parse("2027-04-25T10:00:00Z");
        LinkedHashMap<String, Integer> limits = new LinkedHashMap<>();
        limits.put("max_apps", 5);
        limits.put("max_agents", 10);
        LicenseInfo info = new LicenseInfo(id, "acme", "label", limits, now, exp, 0);

        String t1 = LicenseMinter.mint(info, kp.getPrivate());
        String t2 = LicenseMinter.mint(info, kp.getPrivate());
        assertThat(t1).isEqualTo(t2);
    }
}
