package com.cameleer.server.core.license;

import org.junit.jupiter.api.Test;

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

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

class LicenseStateMachineTest {

    @Test
    void noLicense_isAbsent() {
        assertThat(LicenseStateMachine.classify(null, null)).isEqualTo(LicenseState.ABSENT);
    }

    @Test
    void invalidReason_isInvalid() {
        assertThat(LicenseStateMachine.classify(null, "signature failed")).isEqualTo(LicenseState.INVALID);
    }

    @Test
    void activeBeforeExp() {
        LicenseInfo info = info(Instant.now().plusSeconds(86400), 0);
        assertThat(LicenseStateMachine.classify(info, null)).isEqualTo(LicenseState.ACTIVE);
    }

    @Test
    void graceWithinGracePeriod() {
        LicenseInfo info = info(Instant.now().minusSeconds(86400), 7);
        assertThat(LicenseStateMachine.classify(info, null)).isEqualTo(LicenseState.GRACE);
    }

    @Test
    void expiredAfterGrace() {
        LicenseInfo info = info(Instant.now().minusSeconds(8L * 86400), 7);
        assertThat(LicenseStateMachine.classify(info, null)).isEqualTo(LicenseState.EXPIRED);
    }

    @Test
    void expiredImmediatelyWithZeroGrace() {
        LicenseInfo info = info(Instant.now().minusSeconds(60), 0);
        assertThat(LicenseStateMachine.classify(info, null)).isEqualTo(LicenseState.EXPIRED);
    }

    @Test
    void invalidWinsOverPresentLicense() {
        LicenseInfo info = info(Instant.now().plusSeconds(86400), 0);
        assertThat(LicenseStateMachine.classify(info, "tenant mismatch")).isEqualTo(LicenseState.INVALID);
    }

    private LicenseInfo info(Instant exp, int graceDays) {
        return new LicenseInfo(UUID.randomUUID(), "acme", null, Map.of(),
                Instant.now().minusSeconds(3600), exp, graceDays);
    }
}
