package com.cameleer.server.app.license;

import com.cameleer.server.core.license.LicenseInfo;
import com.cameleer.server.core.license.LicenseState;
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 LicenseMessageRendererTest {

    @Test
    void absent_message() {
        var msg = LicenseMessageRenderer.forCap(LicenseState.ABSENT, null, "max_apps", 0, 3);
        assertThat(msg).contains("No license").contains("max_apps").contains("3");
    }

    @Test
    void active_message() {
        LicenseInfo info = info(Instant.now().plusSeconds(86400 * 100), 0);
        var msg = LicenseMessageRenderer.forCap(LicenseState.ACTIVE, info, "max_apps", 50, 50);
        assertThat(msg).contains("cap reached").contains("50");
    }

    @Test
    void grace_message_includesDayCount() {
        LicenseInfo info = info(Instant.now().minusSeconds(86400L * 5), 30);
        var msg = LicenseMessageRenderer.forCap(LicenseState.GRACE, info, "max_apps", 10, 10);
        assertThat(msg).contains("expired").contains("5").contains("grace");
    }

    @Test
    void expired_message_explainsRevert() {
        LicenseInfo info = info(Instant.now().minusSeconds(86400L * 60), 30);
        var msg = LicenseMessageRenderer.forCap(LicenseState.EXPIRED, info, "max_apps", 40, 3);
        assertThat(msg).contains("expired").contains("default tier").contains("3");
    }

    @Test
    void invalid_message_includesReason() {
        var msg = LicenseMessageRenderer.forCap(LicenseState.INVALID, null,
                "max_apps", 0, 3, "signature failed");
        assertThat(msg).contains("rejected").contains("signature failed");
    }

    @Test
    void forState_absent() {
        var msg = LicenseMessageRenderer.forState(LicenseState.ABSENT, null);
        assertThat(msg).contains("No license").contains("default tier");
    }

    @Test
    void forState_active() {
        LicenseInfo info = info(Instant.now().plusSeconds(86400 * 100), 0);
        var msg = LicenseMessageRenderer.forState(LicenseState.ACTIVE, info);
        assertThat(msg).contains("License is active");
    }

    @Test
    void forState_grace() {
        LicenseInfo info = info(Instant.now().minusSeconds(86400L * 5), 30);
        var msg = LicenseMessageRenderer.forState(LicenseState.GRACE, info);
        assertThat(msg).contains("expired").contains("grace");
    }

    @Test
    void forState_expired() {
        LicenseInfo info = info(Instant.now().minusSeconds(86400L * 60), 30);
        var msg = LicenseMessageRenderer.forState(LicenseState.EXPIRED, info);
        assertThat(msg).contains("expired").contains("default tier");
    }

    @Test
    void forState_invalid_includesReason() {
        var msg = LicenseMessageRenderer.forState(LicenseState.INVALID, null, "signature failed");
        assertThat(msg).contains("rejected").contains("signature failed");
    }

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