package io.cameleer.server.app.license;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * Daily revalidation cron + on-startup revalidation 60s after {@link ApplicationReadyEvent}.
 *
 * <p>The startup tick catches ABSENT-&gt;ACTIVE transitions when the license was written to
 * PostgreSQL between server starts (e.g. SaaS provisioning), and gives slow downstream
 * components time to come up before the first license event fires. The daily cron ensures
 * expirations and clock drift are caught even in long-running deployments.</p>
 *
 * <p>Both invocations call {@link LicenseService#revalidate()} which is internally idempotent
 * and exception-safe; this class additionally swallows any escape so a misbehaving validator
 * cannot crash the scheduler thread.</p>
 */
@Component
public class LicenseRevalidationJob {

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

    private final LicenseService svc;

    public LicenseRevalidationJob(LicenseService svc) {
        this.svc = svc;
    }

    @EventListener(ApplicationReadyEvent.class)
    @Async
    public void onStartup() {
        try {
            Thread.sleep(60_000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return;
        }
        revalidate();
    }

    @Scheduled(cron = "0 0 3 * * *")
    public void daily() {
        revalidate();
    }

    private void revalidate() {
        try {
            svc.revalidate();
        } catch (Exception e) {
            log.error("Revalidation crashed: {}", e.getMessage());
        }
    }
}
