"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.evaluateTerminalReminderCadence = exports.applyReminderCadenceStateUpdate = exports.advanceReminderGracePeriod = exports.TERMINAL_REMINDER_RANDOM_SHOW_THRESHOLD = exports.REMINDER_GRACE_PERIOD_MILLISECONDS = exports.REMINDER_GRACE_ELIGIBLE_COMMAND_LIMIT = exports.writeReminderState = exports.serializeReminderState = exports.resolveReminderStatePath = exports.readReminderState = exports.parseReminderStateValue = exports.parseReminderStateContents = exports.createUnreadableReminderStateDiagnostic = exports.createReminderStateInitializationOptions = exports.createMissingReminderState = exports.REMINDER_STATE_SCHEMA_VERSION = exports.REMINDER_STATE_FILE_NAME = exports.DAY_SHIFT_REMINDER_SEED_ENV = void 0;
exports.evaluateInvalidLicenseWarningPolicy = evaluateInvalidLicenseWarningPolicy;
exports.applyInvalidLicenseWarningStateUpdate = applyInvalidLicenseWarningStateUpdate;
exports.createReminderStatusDiagnostics = createReminderStatusDiagnostics;
const reminder_storage_1 = require("./reminder-storage");
const reminder_cadence_1 = require("./reminder-cadence");
var reminder_storage_2 = require("./reminder-storage");
Object.defineProperty(exports, "DAY_SHIFT_REMINDER_SEED_ENV", { enumerable: true, get: function () { return reminder_storage_2.DAY_SHIFT_REMINDER_SEED_ENV; } });
Object.defineProperty(exports, "REMINDER_STATE_FILE_NAME", { enumerable: true, get: function () { return reminder_storage_2.REMINDER_STATE_FILE_NAME; } });
Object.defineProperty(exports, "REMINDER_STATE_SCHEMA_VERSION", { enumerable: true, get: function () { return reminder_storage_2.REMINDER_STATE_SCHEMA_VERSION; } });
Object.defineProperty(exports, "createMissingReminderState", { enumerable: true, get: function () { return reminder_storage_2.createMissingReminderState; } });
Object.defineProperty(exports, "createReminderStateInitializationOptions", { enumerable: true, get: function () { return reminder_storage_2.createReminderStateInitializationOptions; } });
Object.defineProperty(exports, "createUnreadableReminderStateDiagnostic", { enumerable: true, get: function () { return reminder_storage_2.createUnreadableReminderStateDiagnostic; } });
Object.defineProperty(exports, "parseReminderStateContents", { enumerable: true, get: function () { return reminder_storage_2.parseReminderStateContents; } });
Object.defineProperty(exports, "parseReminderStateValue", { enumerable: true, get: function () { return reminder_storage_2.parseReminderStateValue; } });
Object.defineProperty(exports, "readReminderState", { enumerable: true, get: function () { return reminder_storage_2.readReminderState; } });
Object.defineProperty(exports, "resolveReminderStatePath", { enumerable: true, get: function () { return reminder_storage_2.resolveReminderStatePath; } });
Object.defineProperty(exports, "serializeReminderState", { enumerable: true, get: function () { return reminder_storage_2.serializeReminderState; } });
Object.defineProperty(exports, "writeReminderState", { enumerable: true, get: function () { return reminder_storage_2.writeReminderState; } });
var reminder_cadence_2 = require("./reminder-cadence");
Object.defineProperty(exports, "REMINDER_GRACE_ELIGIBLE_COMMAND_LIMIT", { enumerable: true, get: function () { return reminder_cadence_2.REMINDER_GRACE_ELIGIBLE_COMMAND_LIMIT; } });
Object.defineProperty(exports, "REMINDER_GRACE_PERIOD_MILLISECONDS", { enumerable: true, get: function () { return reminder_cadence_2.REMINDER_GRACE_PERIOD_MILLISECONDS; } });
Object.defineProperty(exports, "TERMINAL_REMINDER_RANDOM_SHOW_THRESHOLD", { enumerable: true, get: function () { return reminder_cadence_2.TERMINAL_REMINDER_RANDOM_SHOW_THRESHOLD; } });
Object.defineProperty(exports, "advanceReminderGracePeriod", { enumerable: true, get: function () { return reminder_cadence_2.advanceReminderGracePeriod; } });
Object.defineProperty(exports, "applyReminderCadenceStateUpdate", { enumerable: true, get: function () { return reminder_cadence_2.applyReminderCadenceStateUpdate; } });
Object.defineProperty(exports, "evaluateTerminalReminderCadence", { enumerable: true, get: function () { return reminder_cadence_2.evaluateTerminalReminderCadence; } });
function evaluateInvalidLicenseWarningPolicy(options) {
    const commandCompletedAt = (0, reminder_storage_1.utcTimestampValue)(options.commandCompletedAt);
    if (commandCompletedAt === undefined) {
        throw new TypeError("commandCompletedAt must be a UTC RFC 3339 timestamp");
    }
    const warning = createInvalidLicenseWarningDiagnostic(options.licenseStatus);
    const lastInvalidLicenseWarningAt = options.reminderState?.lastInvalidLicenseWarningAt
        ?? options.reminderStateLoadDiagnostic?.last_invalid_license_warning_at
        ?? null;
    if (warning === null) {
        const reason = noWarningReason(options.licenseStatus);
        return invalidLicenseWarningDecision({
            state: options.reminderState ?? null,
            reason,
            warningVisible: false,
            warningSuppressed: false,
            writeSuppressedReason: reason,
            commandCompletedAt,
            humanReadableWarningEligible: options.humanReadableWarningEligible,
            lastInvalidLicenseWarningAt,
            warning: null
        });
    }
    const warningWithState = {
        ...warning,
        last_invalid_license_warning_at: lastInvalidLicenseWarningAt
    };
    if (!options.humanReadableWarningEligible) {
        return invalidLicenseWarningDecision({
            state: options.reminderState ?? null,
            reason: "human_readable_output_suppression",
            warningVisible: false,
            warningSuppressed: true,
            writeSuppressedReason: "human_readable_output_suppression",
            commandCompletedAt,
            humanReadableWarningEligible: false,
            lastInvalidLicenseWarningAt,
            warning: warningWithState
        });
    }
    if (lastInvalidLicenseWarningAt !== null) {
        return invalidLicenseWarningDecision({
            state: options.reminderState ?? null,
            reason: "repeat_suppression",
            warningVisible: false,
            warningSuppressed: true,
            writeSuppressedReason: "repeat_suppression",
            commandCompletedAt,
            humanReadableWarningEligible: true,
            lastInvalidLicenseWarningAt,
            warning: warningWithState
        });
    }
    const state = options.reminderState === undefined || options.reminderState === null
        ? null
        : {
            ...options.reminderState,
            lastInvalidLicenseWarningAt: commandCompletedAt
        };
    const visibleWarning = {
        ...warning,
        last_invalid_license_warning_at: commandCompletedAt
    };
    return invalidLicenseWarningDecision({
        state,
        reason: warning.warning_source === "configured-license"
            ? "configured_license_warning"
            : "installed_license_warning",
        warningVisible: true,
        warningSuppressed: false,
        writeSuppressedReason: null,
        commandCompletedAt,
        humanReadableWarningEligible: true,
        lastInvalidLicenseWarningAt: commandCompletedAt,
        warning: visibleWarning
    });
}
function applyInvalidLicenseWarningStateUpdate(options) {
    const commandCompletedAt = (0, reminder_storage_1.utcTimestampValue)(options.commandCompletedAt);
    if (commandCompletedAt === undefined) {
        throw new TypeError("commandCompletedAt must be a UTC RFC 3339 timestamp");
    }
    const resolvedPath = (0, reminder_storage_1.resolveReminderStatePath)(options);
    const preflightDecision = evaluateInvalidLicenseWarningPolicy({
        licenseStatus: options.licenseStatus,
        reminderState: null,
        commandCompletedAt,
        humanReadableWarningEligible: options.humanReadableWarningEligible
    });
    if (preflightDecision.warningDiagnostic === null ||
        !options.humanReadableWarningEligible) {
        return invalidLicenseWarningStateUpdateResult({
            resolvedPath,
            readStatus: "not-read",
            stateWritten: false,
            state: null,
            decision: preflightDecision
        });
    }
    const stateInput = loadInvalidLicenseWarningUpdateState(options, commandCompletedAt);
    const decision = evaluateInvalidLicenseWarningPolicy({
        licenseStatus: options.licenseStatus,
        reminderState: stateInput.state,
        reminderStateLoadDiagnostic: stateInput.loadDiagnostic,
        commandCompletedAt,
        humanReadableWarningEligible: true
    });
    if (!decision.warningVisible || decision.state === null) {
        return invalidLicenseWarningStateUpdateResult({
            resolvedPath,
            readStatus: stateInput.readStatus,
            stateWritten: false,
            state: stateInput.state,
            decision
        });
    }
    const writtenPath = (0, reminder_storage_1.writeReminderState)(decision.state, options);
    return invalidLicenseWarningStateUpdateResult({
        resolvedPath: writtenPath,
        readStatus: stateInput.readStatus,
        stateWritten: true,
        state: decision.state,
        decision
    });
}
function createReminderStatusDiagnostics(options) {
    const commandCompletedAt = (0, reminder_storage_1.utcTimestampValue)(options.commandCompletedAt);
    if (commandCompletedAt === undefined) {
        throw new TypeError("commandCompletedAt must be a UTC RFC 3339 timestamp");
    }
    if (options.licenseStatus.suppresses_reminders) {
        const warningDecision = evaluateInvalidLicenseWarningPolicy({
            licenseStatus: options.licenseStatus,
            reminderState: null,
            commandCompletedAt,
            humanReadableWarningEligible: true
        });
        return reminderStatusDiagnostics({
            readStatus: "not-read",
            stateDirectorySource: null,
            loadDiagnostic: null,
            state: null,
            gracePeriodState: "suppressed_by_license",
            nextReminderWindow: {
                kind: "suppressed_by_license",
                eligible_command_ordinal_since_last_reminder: null,
                eligible_commands_until_next_window: null,
                milliseconds_until_grace_ends: null,
                random_show_threshold: null
            },
            warningThrottle: warningDecision.diagnostic
        });
    }
    const readResult = (0, reminder_storage_1.readReminderState)({
        ...options,
        newState: (0, reminder_storage_1.createReminderStateInitializationOptions)({
            firstEligibleCommandAt: commandCompletedAt,
            prngSeed: options.prngSeed,
            env: options.env,
            allowTestSeedFromEnvironment: options.allowTestSeedFromEnvironment,
            randomSeedBytes: options.randomSeedBytes
        })
    });
    const graceStatus = (0, reminder_cadence_1.evaluateGraceStatus)(readResult.state, commandCompletedAt);
    const warningDecision = evaluateInvalidLicenseWarningPolicy({
        licenseStatus: options.licenseStatus,
        reminderState: readResult.state,
        reminderStateLoadDiagnostic: readResult.loadDiagnostic,
        commandCompletedAt,
        humanReadableWarningEligible: true
    });
    return reminderStatusDiagnostics({
        readStatus: readResult.status,
        stateDirectorySource: readResult.stateDirectorySource,
        loadDiagnostic: readResult.loadDiagnostic,
        state: readResult.state,
        gracePeriodState: graceStatus.graceActive ? "active" : "ended",
        nextReminderWindow: createReminderStatusNextWindow(readResult.state, graceStatus),
        warningThrottle: warningDecision.diagnostic
    });
}
function reminderStatusDiagnostics(options) {
    return {
        read_status: options.readStatus,
        state_directory_source: options.stateDirectorySource,
        schema_version: options.loadDiagnostic?.schema_version ?? null,
        recovery_reason: options.loadDiagnostic?.recovery_reason ?? null,
        ...(options.loadDiagnostic?.recovery_field === undefined
            ? {}
            : { recovery_field: options.loadDiagnostic.recovery_field }),
        grace_period_state: options.gracePeriodState,
        grace_eligible_command_limit: reminder_cadence_1.REMINDER_GRACE_ELIGIBLE_COMMAND_LIMIT,
        grace_period_milliseconds: reminder_cadence_1.REMINDER_GRACE_PERIOD_MILLISECONDS,
        first_eligible_command_at: options.state?.firstEligibleCommandAt ?? null,
        eligible_command_count: options.state?.eligibleCommandCount ?? null,
        last_reminder_at: options.state?.lastReminderAt ?? null,
        eligible_commands_since_last_reminder: options.state?.eligibleCommandsSinceLastReminder ?? null,
        last_invalid_license_warning_at: options.state?.lastInvalidLicenseWarningAt ?? null,
        next_reminder_window: options.nextReminderWindow,
        warning_throttle: options.warningThrottle
    };
}
function createReminderStatusNextWindow(state, graceStatus) {
    if (graceStatus.graceActive) {
        return {
            kind: "grace_period",
            eligible_command_ordinal_since_last_reminder: null,
            eligible_commands_until_next_window: Math.max(reminder_cadence_1.REMINDER_GRACE_ELIGIBLE_COMMAND_LIMIT - state.eligibleCommandCount, 0),
            milliseconds_until_grace_ends: graceStatus.elapsedMilliseconds === null
                ? reminder_cadence_1.REMINDER_GRACE_PERIOD_MILLISECONDS
                : Math.max(reminder_cadence_1.REMINDER_GRACE_PERIOD_MILLISECONDS - graceStatus.elapsedMilliseconds, 0),
            random_show_threshold: null
        };
    }
    if (state.lastReminderAt === null) {
        return {
            kind: "first_reminder",
            eligible_command_ordinal_since_last_reminder: null,
            eligible_commands_until_next_window: 1,
            milliseconds_until_grace_ends: null,
            random_show_threshold: null
        };
    }
    const nextOrdinal = state.eligibleCommandsSinceLastReminder + 1;
    if (nextOrdinal <= 2) {
        return {
            kind: "post_reminder_suppression_window",
            eligible_command_ordinal_since_last_reminder: nextOrdinal,
            eligible_commands_until_next_window: 3 - state.eligibleCommandsSinceLastReminder,
            milliseconds_until_grace_ends: null,
            random_show_threshold: null
        };
    }
    if (nextOrdinal <= 4) {
        return {
            kind: "random_chance",
            eligible_command_ordinal_since_last_reminder: nextOrdinal,
            eligible_commands_until_next_window: 1,
            milliseconds_until_grace_ends: null,
            random_show_threshold: reminder_cadence_1.TERMINAL_REMINDER_RANDOM_SHOW_THRESHOLD
        };
    }
    return {
        kind: "forced_fifth_command",
        eligible_command_ordinal_since_last_reminder: nextOrdinal,
        eligible_commands_until_next_window: 1,
        milliseconds_until_grace_ends: null,
        random_show_threshold: null
    };
}
function loadInvalidLicenseWarningUpdateState(options, commandCompletedAt) {
    if (options.state !== undefined) {
        return {
            state: options.state,
            readStatus: "provided-state",
            loadDiagnostic: null
        };
    }
    const readResult = (0, reminder_storage_1.readReminderState)({
        ...options,
        newState: (0, reminder_storage_1.createReminderStateInitializationOptions)({
            firstEligibleCommandAt: commandCompletedAt,
            prngSeed: options.prngSeed,
            env: options.env,
            allowTestSeedFromEnvironment: options.allowTestSeedFromEnvironment,
            randomSeedBytes: options.randomSeedBytes
        })
    });
    return {
        state: readResult.state,
        readStatus: readResult.status,
        loadDiagnostic: readResult.loadDiagnostic
    };
}
function createInvalidLicenseWarningDiagnostic(licenseStatus) {
    if (licenseStatus.configured_license_diagnostic !== null) {
        const configuredDiagnostic = licenseStatus.configured_license_diagnostic;
        return {
            warning_source: "configured-license",
            reason_code: configuredDiagnostic.reason_code,
            configured_failure_kind: configuredDiagnostic.failure_kind,
            configured_source: configuredDiagnostic.source,
            configured_label: configuredDiagnostic.label,
            license_path: configuredDiagnostic.configured_path,
            fallback_mode: configuredDiagnostic.fallback_mode,
            suppresses_reminders: false,
            selected_source: licenseStatus.selected_source.source,
            selected_source_found: licenseStatus.selected_source.found,
            selected_source_readable: licenseStatus.selected_source.readable
        };
    }
    if (licenseStatus.effective_status !== "invalid-license" ||
        licenseStatus.suppresses_reminders ||
        licenseStatus.selected_suppressing_license_id !== null ||
        licenseStatus.reason_code === "missing") {
        return null;
    }
    return {
        warning_source: "installed-license",
        reason_code: licenseStatus.reason_code,
        configured_failure_kind: null,
        configured_source: null,
        configured_label: null,
        license_path: licenseStatus.license_path,
        fallback_mode: licenseStatus.fallback_mode,
        suppresses_reminders: false,
        selected_source: licenseStatus.selected_source.source,
        selected_source_found: licenseStatus.selected_source.found,
        selected_source_readable: licenseStatus.selected_source.readable
    };
}
function noWarningReason(licenseStatus) {
    if (licenseStatus.effective_status === "unlicensed" &&
        licenseStatus.reason_code === "missing" &&
        !licenseStatus.configured_source.configured) {
        return "missing_unconfigured_license";
    }
    if (licenseStatus.suppresses_reminders || licenseStatus.effective_status === "licensed") {
        return "license_status_suppression";
    }
    return "no_invalid_license_warning";
}
function invalidLicenseWarningDecision(options) {
    return {
        state: options.state,
        reason: options.reason,
        warningVisible: options.warningVisible,
        warningSuppressed: options.warningSuppressed,
        warningDiagnostic: options.warning,
        diagnostic: {
            warning_eligible: options.warning !== null,
            warning_visible: options.warningVisible,
            warning_suppressed: options.warningSuppressed,
            decision_reason: options.reason,
            write_suppressed_reason: options.writeSuppressedReason,
            command_completed_at: options.commandCompletedAt,
            human_readable_warning_eligible: options.humanReadableWarningEligible,
            last_invalid_license_warning_at: options.lastInvalidLicenseWarningAt,
            warning: options.warning
        }
    };
}
function invalidLicenseWarningStateUpdateResult(options) {
    return {
        state: options.state,
        statePath: options.resolvedPath.statePath,
        stateDirectory: options.resolvedPath.stateDirectory,
        stateDirectorySource: options.resolvedPath.stateDirectorySource,
        reason: options.decision.reason,
        stateWritten: options.stateWritten,
        warningVisible: options.decision.warningVisible,
        warningSuppressed: options.decision.warningSuppressed,
        warningDiagnostic: options.decision.warningDiagnostic,
        decision: options.decision,
        diagnostic: {
            state_path: options.resolvedPath.statePath,
            state_directory_source: options.resolvedPath.stateDirectorySource,
            read_status: options.readStatus,
            write_suppressed_reason: options.decision.diagnostic.write_suppressed_reason,
            state_written: options.stateWritten,
            last_invalid_license_warning_at: options.state?.lastInvalidLicenseWarningAt
                ?? options.decision.diagnostic.last_invalid_license_warning_at
        }
    };
}
