"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ARTIFACT_LICENSE_REMINDER_COPY_VARIANTS = exports.ARTIFACT_LICENSE_REMINDER_HORIZONTAL_BORDER_CHARACTERS = exports.OFFICIAL_DAY_SHIFT_LICENSE_PURCHASE_URL = exports.ARTIFACT_LICENSE_REMINDER_END_MARKER = exports.ARTIFACT_LICENSE_REMINDER_START_MARKER = void 0;
exports.renderArtifactLicenseReminder = renderArtifactLicenseReminder;
exports.placeArtifactLicenseReminder = placeArtifactLicenseReminder;
exports.selectArtifactLicenseReminderTargets = selectArtifactLicenseReminderTargets;
exports.selectArtifactLicenseReminderTargetSelection = selectArtifactLicenseReminderTargetSelection;
exports.selectArtifactLicenseReminderTargetsFromCandidates = selectArtifactLicenseReminderTargetsFromCandidates;
exports.boundArtifactLicenseReminderTargetsByLayer = boundArtifactLicenseReminderTargetsByLayer;
exports.inspectArtifactLicenseReminderStaleness = inspectArtifactLicenseReminderStaleness;
exports.refreshArtifactLicenseReminderRegion = refreshArtifactLicenseReminderRegion;
exports.ensureArtifactLicenseReminderRegion = ensureArtifactLicenseReminderRegion;
exports.removeArtifactLicenseReminderRegions = removeArtifactLicenseReminderRegions;
exports.cleanupPlanningLicenseReminders = cleanupPlanningLicenseReminders;
exports.ensureFallbackArtifactLicenseReminderFile = ensureFallbackArtifactLicenseReminderFile;
exports.applyPersistedArtifactLicenseReminderWrites = applyPersistedArtifactLicenseReminderWrites;
exports.formatArtifactReminderGeneratedDate = formatArtifactReminderGeneratedDate;
exports.extractArtifactReminderGeneratedDate = extractArtifactReminderGeneratedDate;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const paths_1 = require("../paths");
const command_write_summary_1 = require("./command-write-summary");
const license_guidance_1 = require("./license-guidance");
exports.ARTIFACT_LICENSE_REMINDER_START_MARKER = "<!-- day-shift:license-reminder:start -->";
exports.ARTIFACT_LICENSE_REMINDER_END_MARKER = "<!-- day-shift:license-reminder:end -->";
var license_guidance_2 = require("./license-guidance");
Object.defineProperty(exports, "OFFICIAL_DAY_SHIFT_LICENSE_PURCHASE_URL", { enumerable: true, get: function () { return license_guidance_2.OFFICIAL_DAY_SHIFT_LICENSE_PURCHASE_URL; } });
exports.ARTIFACT_LICENSE_REMINDER_HORIZONTAL_BORDER_CHARACTERS = [
    "!",
    "#",
    "$",
    "%",
    "&",
    "(",
    ")",
    "*",
    "+",
    ",",
    "-",
    ".",
    "/",
    ":",
    ";",
    "<",
    "=",
    ">",
    "?",
    "@",
    "[",
    "]",
    "^",
    "_",
    "{",
    "|",
    "}",
    "~"
];
exports.ARTIFACT_LICENSE_REMINDER_COPY_VARIANTS = [
    ["This is your reminder that purchasing a Day Shift key", "removes these messages."],
    ["Day Shift is usable without a key.", "Buying a key removes this reminder."],
    ["Companies can purchase Day Shift", "to remove unlicensed reminders."],
    ["A Day Shift key keeps commercial use quiet", "by removing license reminders."],
    ["Unlicensed Day Shift runs keep this reminder visible", "until a key is installed."],
    ["Purchase a Day Shift key for your team", "to stop these artifact reminders."],
    ["Day Shift reminders are removed after licensing", "with a valid commercial key."],
    ["Commercial teams can keep generated artifacts clean", "by purchasing a Day Shift key."],
    ["Install a valid Day Shift license key", "to suppress this managed reminder."],
    ["This reminder stays visible for unlicensed use", "and disappears after purchase."]
];
const BOX_CONTENT_WIDTH = 62;
const HORIZONTAL_BORDER_WIDTH = BOX_CONTENT_WIDTH + 4;
const ARTIFACT_REMINDER_STALE_AFTER_DAYS = 30;
const DATE_ONLY_MILLISECONDS = 24 * 60 * 60 * 1000;
const ARTIFACT_REMINDER_TARGET_KINDS = new Set([
    "slice-overview",
    "phase-overview",
    "milestone-overview",
    "milestone-reconciliation"
]);
const ARTIFACT_REMINDER_TARGET_LAYER_ORDER = new Map([
    ["slice", 0],
    ["phase", 1],
    ["milestone", 2],
    ["reconciliation", 3]
]);
function renderArtifactLicenseReminder(options = {}) {
    const random = options.random ?? Math.random;
    const generatedDate = formatArtifactReminderGeneratedDate(options.generatedAt ?? new Date());
    const copyLines = selectReminderCopy(random);
    const bodyLines = [
        buildHorizontalBorder(random),
        ...copyLines.map(formatBoxLine),
        formatBoxLine(`Purchase: ${license_guidance_1.OFFICIAL_DAY_SHIFT_LICENSE_PURCHASE_URL}`),
        formatBoxLine(`Generated: ${generatedDate}`),
        buildHorizontalBorder(random)
    ];
    return [
        exports.ARTIFACT_LICENSE_REMINDER_START_MARKER,
        "```text",
        ...bodyLines,
        "```",
        exports.ARTIFACT_LICENSE_REMINDER_END_MARKER,
        ""
    ].join("\n");
}
function placeArtifactLicenseReminder(options) {
    const lineEnding = detectLineEnding(options.markdownText);
    const markdownText = normalizeLineEndings(options.markdownText);
    const managedRegion = normalizeManagedRegion(options.managedRegion);
    const existingRegion = findExistingManagedRegion(markdownText);
    if (existingRegion !== null) {
        return restoreLineEndings(`${markdownText.slice(0, existingRegion.startIndex)}${managedRegion}${markdownText.slice(existingRegion.endIndex)}`, lineEnding);
    }
    return restoreLineEndings(insertManagedRegion(markdownText, findReminderInsertionIndex(markdownText), managedRegion), lineEnding);
}
function selectArtifactLicenseReminderTargets(options) {
    return selectArtifactLicenseReminderTargetSelection(options).targets;
}
function selectArtifactLicenseReminderTargetSelection(options) {
    const eligibility = (0, command_write_summary_1.classifyReminderEligibilityFromCommandSummary)(options.summary);
    const parentTargets = eligibility.persistedReminderEligible
        ? selectArtifactLicenseReminderTargetsFromCandidates({
            persistedCandidateArtifacts: eligibility.persistedCandidateArtifacts
        })
        : [];
    if (parentTargets.length > 0) {
        return {
            targets: parentTargets,
            reason: "skipped-parent-target-exists",
            parentTargets
        };
    }
    if (!summaryIsEligibleForFallbackArtifactReminder(options.summary)) {
        return {
            targets: [],
            reason: "skipped-not-eligible",
            parentTargets
        };
    }
    const fallback = selectFallbackArtifactLicenseReminderTarget(options.summary);
    if (fallback === null) {
        return {
            targets: [],
            reason: "skipped-no-planning-root",
            parentTargets
        };
    }
    return {
        targets: [fallback.targetPath],
        reason: "fallback-selected",
        parentTargets,
        fallbackTarget: fallback.targetPath,
        fallbackSourcePath: fallback.sourcePath
    };
}
function selectArtifactLicenseReminderTargetsFromCandidates(options) {
    return boundArtifactLicenseReminderTargetsByLayer(options.persistedCandidateArtifacts).map((artifact) => artifact.path);
}
function boundArtifactLicenseReminderTargetsByLayer(persistedCandidateArtifacts) {
    const targetsByPath = new Map();
    for (const artifact of persistedCandidateArtifacts) {
        if (ARTIFACT_REMINDER_TARGET_KINDS.has(artifact.artifactKind)) {
            targetsByPath.set(artifact.path, artifact);
        }
    }
    const targetsByLayer = new Map();
    for (const artifact of [...targetsByPath.values()].sort(compareArtifactReminderTargetClassifications)) {
        if (!targetsByLayer.has(artifact.layer)) {
            targetsByLayer.set(artifact.layer, artifact);
        }
    }
    return [...targetsByLayer.values()].sort(compareArtifactReminderTargetClassifications);
}
function inspectArtifactLicenseReminderStaleness(options) {
    const markdownText = normalizeLineEndings(options.markdownText);
    const existingRegion = findExistingManagedRegion(markdownText);
    if (existingRegion === null) {
        throw new Error("Artifact markdown must contain exactly one complete managed license reminder marker pair.");
    }
    const managedRegion = markdownText.slice(existingRegion.startIndex, existingRegion.endIndex);
    const generatedDateExtraction = extractArtifactReminderGeneratedDate(managedRegion);
    if (generatedDateExtraction === null) {
        return { isStale: false, reason: "missing-generated-date" };
    }
    if (!isValidDateOnly(generatedDateExtraction)) {
        return {
            isStale: false,
            reason: "malformed-generated-date",
            generatedDate: generatedDateExtraction
        };
    }
    const generatedUtcDay = parseDateOnlyUtcDay(generatedDateExtraction);
    const currentUtcDay = parseDateOnlyUtcDay(formatArtifactReminderGeneratedDate(options.currentDate));
    const ageInDays = Math.floor((currentUtcDay - generatedUtcDay) / DATE_ONLY_MILLISECONDS);
    if (ageInDays < 0) {
        return {
            isStale: false,
            reason: "future-generated-date",
            generatedDate: generatedDateExtraction,
            ageInDays
        };
    }
    if (ageInDays > ARTIFACT_REMINDER_STALE_AFTER_DAYS) {
        return {
            isStale: true,
            reason: "stale",
            generatedDate: generatedDateExtraction,
            ageInDays
        };
    }
    return {
        isStale: false,
        reason: ageInDays === ARTIFACT_REMINDER_STALE_AFTER_DAYS
            ? "exactly-thirty-days-old"
            : "fresh",
        generatedDate: generatedDateExtraction,
        ageInDays
    };
}
function refreshArtifactLicenseReminderRegion(options) {
    const lineEnding = detectLineEnding(options.markdownText);
    const markdownText = normalizeLineEndings(options.markdownText);
    const existingRegion = findExistingManagedRegion(markdownText);
    if (existingRegion === null) {
        return {
            markdownText: options.markdownText,
            refreshed: false,
            reason: "no-managed-region"
        };
    }
    const currentDate = options.currentDate ?? new Date();
    const generatedAt = options.generatedAt ?? currentDate;
    const managedRegion = markdownText.slice(existingRegion.startIndex, existingRegion.endIndex);
    if (!isValidArtifactLicenseReminderManagedRegion(managedRegion)) {
        return {
            markdownText: replaceManagedRegion({
                markdownText,
                managedRegion: renderArtifactLicenseReminder({
                    generatedAt,
                    random: options.random
                }),
                lineEnding
            }),
            refreshed: true,
            reason: "damaged-managed-body"
        };
    }
    const staleness = inspectArtifactLicenseReminderStaleness({
        markdownText,
        currentDate
    });
    if (!staleness.isStale) {
        return {
            markdownText: options.markdownText,
            refreshed: false,
            reason: refreshReasonFromFreshStaleness(staleness),
            staleness
        };
    }
    return {
        markdownText: replaceManagedRegion({
            markdownText,
            managedRegion: renderArtifactLicenseReminder({
                generatedAt,
                random: options.random
            }),
            lineEnding
        }),
        refreshed: true,
        reason: "stale",
        staleness
    };
}
function ensureArtifactLicenseReminderRegion(options) {
    const refreshed = refreshArtifactLicenseReminderRegion(options);
    if (refreshed.reason !== "no-managed-region") {
        return {
            markdownText: refreshed.markdownText,
            changed: refreshed.refreshed,
            reason: refreshed.reason,
            staleness: refreshed.staleness
        };
    }
    return {
        markdownText: placeArtifactLicenseReminder({
            markdownText: options.markdownText,
            managedRegion: renderArtifactLicenseReminder({
                generatedAt: options.generatedAt ?? options.currentDate ?? new Date(),
                random: options.random
            })
        }),
        changed: true,
        reason: "missing-managed-region"
    };
}
function removeArtifactLicenseReminderRegions(options) {
    const lineEnding = detectLineEnding(options.markdownText);
    const markdownText = normalizeLineEndings(options.markdownText);
    const regions = findAllCompleteManagedRegions(markdownText);
    if (regions.length === 0) {
        return {
            markdownText: options.markdownText,
            removedRegionCount: 0
        };
    }
    let cleaned = "";
    let previousEndIndex = 0;
    for (const region of regions) {
        cleaned += markdownText.slice(previousEndIndex, region.startIndex);
        previousEndIndex = region.endIndex;
    }
    cleaned += markdownText.slice(previousEndIndex);
    return {
        markdownText: restoreLineEndings(cleaned, lineEnding),
        removedRegionCount: regions.length
    };
}
function cleanupPlanningLicenseReminders(options = {}) {
    const repositoryRoot = node_path_1.default.resolve(options.repositoryRoot ?? process.cwd());
    const planningRoot = node_path_1.default.resolve(options.planningRoot ?? node_path_1.default.join(repositoryRoot, ".day-shift", "planning"));
    assertPathInsideRepositoryRoot(planningRoot, repositoryRoot);
    const dryRun = options.dryRun === true;
    const plannedOperations = [];
    let scannedFileCount = 0;
    if (!node_fs_1.default.existsSync(planningRoot)) {
        return {
            planningRoot,
            dryRun,
            changed: false,
            changedPaths: [],
            operations: [],
            scannedFileCount
        };
    }
    const stats = node_fs_1.default.statSync(planningRoot);
    if (!stats.isDirectory()) {
        throw new Error("Planning root must be a directory.");
    }
    for (const absolutePath of listCleanupCandidateFiles(planningRoot)) {
        scannedFileCount += 1;
        const relativePath = toRepositoryRelativePath(repositoryRoot, absolutePath);
        const existingMarkdown = node_fs_1.default.readFileSync(absolutePath, "utf8");
        const removed = removeArtifactLicenseReminderRegions({
            markdownText: existingMarkdown
        });
        if (removed.removedRegionCount === 0) {
            continue;
        }
        const action = shouldDeleteCleanedFallbackReminderFile(absolutePath, removed.markdownText)
            ? "delete"
            : "rewrite";
        plannedOperations.push({
            operation: {
                path: relativePath,
                action,
                removedRegionCount: removed.removedRegionCount
            },
            absolutePath,
            cleanedMarkdown: removed.markdownText
        });
    }
    plannedOperations.sort((left, right) => compareCleanupOperations(left.operation, right.operation));
    if (!dryRun) {
        for (const plannedOperation of plannedOperations) {
            if (plannedOperation.operation.action === "delete") {
                node_fs_1.default.unlinkSync(plannedOperation.absolutePath);
                continue;
            }
            node_fs_1.default.writeFileSync(plannedOperation.absolutePath, plannedOperation.cleanedMarkdown, "utf8");
        }
    }
    const operations = plannedOperations.map((plannedOperation) => plannedOperation.operation);
    return {
        planningRoot,
        dryRun,
        changed: operations.length > 0,
        changedPaths: operations.map((operation) => operation.path),
        operations,
        scannedFileCount
    };
}
function ensureFallbackArtifactLicenseReminderFile(options) {
    const selection = selectArtifactLicenseReminderTargetSelection({ summary: options.summary });
    if (selection.reason !== "fallback-selected" || selection.fallbackTarget === undefined) {
        return {
            selection,
            changed: false,
            created: false,
            reason: selection.reason
        };
    }
    const targetPath = (0, paths_1.parseRepositoryRelativePath)(selection.fallbackTarget).normalizedPath;
    const repositoryRoot = options.repositoryRoot ?? process.cwd();
    const absolutePath = node_path_1.default.resolve(repositoryRoot, targetPath);
    const repositoryRootWithSeparator = node_path_1.default.resolve(repositoryRoot) + node_path_1.default.sep;
    if (absolutePath !== node_path_1.default.resolve(repositoryRoot) &&
        !absolutePath.startsWith(repositoryRootWithSeparator)) {
        throw new Error("Fallback license reminder target must stay inside the repository root.");
    }
    const existed = node_fs_1.default.existsSync(absolutePath);
    const existingMarkdown = existed ? node_fs_1.default.readFileSync(absolutePath, "utf8") : "";
    const ensured = ensureArtifactLicenseReminderRegion({
        markdownText: existingMarkdown,
        currentDate: options.currentDate,
        generatedAt: options.generatedAt,
        random: options.random
    });
    if (ensured.changed || !existed) {
        node_fs_1.default.mkdirSync(node_path_1.default.dirname(absolutePath), { recursive: true });
        node_fs_1.default.writeFileSync(absolutePath, ensured.markdownText, "utf8");
    }
    return {
        selection,
        targetPath,
        absolutePath,
        changed: ensured.changed || !existed,
        created: !existed,
        reason: ensured.reason,
        staleness: ensured.staleness
    };
}
function applyPersistedArtifactLicenseReminderWrites(options) {
    const selection = selectArtifactLicenseReminderTargetSelection({ summary: options.summary });
    if (!options.persistedReminderEligible) {
        return {
            persistedReminderEligible: false,
            changed: false,
            reason: "skipped-cadence-ineligible",
            selection,
            writes: []
        };
    }
    if (selection.parentTargets.length > 0) {
        const writes = selection.parentTargets.map((targetPath) => ensureParentArtifactLicenseReminderWrite({
            targetPath,
            repositoryRoot: options.repositoryRoot,
            currentDate: options.currentDate,
            generatedAt: options.generatedAt,
            random: options.random
        }));
        return {
            persistedReminderEligible: true,
            changed: writes.some((write) => write.changed),
            reason: writes.some((write) => write.changed) ? "changed" : "unchanged",
            selection,
            writes
        };
    }
    if (selection.reason !== "fallback-selected") {
        return {
            persistedReminderEligible: true,
            changed: false,
            reason: selection.reason,
            selection,
            writes: []
        };
    }
    const fallbackResult = ensureFallbackArtifactLicenseReminderFile({
        summary: options.summary,
        repositoryRoot: options.repositoryRoot,
        currentDate: options.currentDate,
        generatedAt: options.generatedAt,
        random: options.random
    });
    if (fallbackResult.targetPath === undefined || fallbackResult.absolutePath === undefined) {
        return {
            persistedReminderEligible: true,
            changed: false,
            reason: fallbackResult.reason,
            selection,
            writes: []
        };
    }
    const writes = [
        {
            targetKind: "fallback",
            targetPath: fallbackResult.targetPath,
            absolutePath: fallbackResult.absolutePath,
            changed: fallbackResult.changed,
            created: fallbackResult.created,
            reason: fallbackResult.reason,
            staleness: fallbackResult.staleness
        }
    ];
    return {
        persistedReminderEligible: true,
        changed: fallbackResult.changed,
        reason: fallbackResult.changed ? "changed" : "unchanged",
        selection,
        writes
    };
}
function formatArtifactReminderGeneratedDate(generatedAt) {
    if (typeof generatedAt === "string") {
        if (/^\d{4}-\d{2}-\d{2}$/.test(generatedAt)) {
            return generatedAt;
        }
        return formatArtifactReminderGeneratedDate(new Date(generatedAt));
    }
    if (Number.isNaN(generatedAt.getTime())) {
        throw new Error("Artifact reminder generated date must be a valid Date or date string.");
    }
    return generatedAt.toISOString().slice(0, 10);
}
function extractArtifactReminderGeneratedDate(managedRegion) {
    for (const line of normalizeLineEndings(managedRegion).split("\n")) {
        const generatedDateMatch = line.match(/\bGenerated:\s*([^\s|!]+)/);
        if (generatedDateMatch) {
            return generatedDateMatch[1];
        }
    }
    return null;
}
function selectReminderCopy(random) {
    return exports.ARTIFACT_LICENSE_REMINDER_COPY_VARIANTS[randomIndex(random, exports.ARTIFACT_LICENSE_REMINDER_COPY_VARIANTS.length)];
}
function buildHorizontalBorder(random) {
    const characters = [];
    for (let index = 0; index < HORIZONTAL_BORDER_WIDTH; index += 1) {
        let character = exports.ARTIFACT_LICENSE_REMINDER_HORIZONTAL_BORDER_CHARACTERS[randomIndex(random, exports.ARTIFACT_LICENSE_REMINDER_HORIZONTAL_BORDER_CHARACTERS.length)];
        if (index > 0 && character === characters[index - 1]) {
            const nextCharacterIndex = (exports.ARTIFACT_LICENSE_REMINDER_HORIZONTAL_BORDER_CHARACTERS.indexOf(character) + 1) %
                exports.ARTIFACT_LICENSE_REMINDER_HORIZONTAL_BORDER_CHARACTERS.length;
            character = exports.ARTIFACT_LICENSE_REMINDER_HORIZONTAL_BORDER_CHARACTERS[nextCharacterIndex];
        }
        characters.push(character);
    }
    return characters.join("");
}
function formatBoxLine(line) {
    if (!/^[\x20-\x7E]*$/.test(line)) {
        throw new Error("Artifact reminder body lines must be ASCII.");
    }
    if (line.length > BOX_CONTENT_WIDTH) {
        throw new Error("Artifact reminder body lines must fit inside the managed reminder box.");
    }
    return `! ${line.padEnd(BOX_CONTENT_WIDTH, " ")} !`;
}
function randomIndex(random, length) {
    const value = random();
    if (!Number.isFinite(value) || value < 0 || value >= 1) {
        throw new Error("Artifact reminder random source must return a finite number in [0, 1).");
    }
    return Math.floor(value * length);
}
function isValidDateOnly(value) {
    if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
        return false;
    }
    const parsedDate = new Date(`${value}T00:00:00.000Z`);
    return !Number.isNaN(parsedDate.getTime()) &&
        formatArtifactReminderGeneratedDate(parsedDate) === value;
}
function parseDateOnlyUtcDay(value) {
    return Date.parse(`${value}T00:00:00.000Z`);
}
function ensureParentArtifactLicenseReminderWrite(options) {
    const targetPath = (0, paths_1.parseRepositoryRelativePath)(options.targetPath).normalizedPath;
    const repositoryRoot = options.repositoryRoot ?? process.cwd();
    const absolutePath = node_path_1.default.resolve(repositoryRoot, targetPath);
    assertPathInsideRepositoryRoot(absolutePath, repositoryRoot);
    const existingMarkdown = node_fs_1.default.readFileSync(absolutePath, "utf8");
    const ensured = ensureArtifactLicenseReminderRegion({
        markdownText: existingMarkdown,
        currentDate: options.currentDate,
        generatedAt: options.generatedAt,
        random: options.random
    });
    if (ensured.changed) {
        node_fs_1.default.writeFileSync(absolutePath, ensured.markdownText, "utf8");
    }
    return {
        targetKind: "parent",
        targetPath,
        absolutePath,
        changed: ensured.changed,
        created: false,
        reason: ensured.reason,
        staleness: ensured.staleness
    };
}
function assertPathInsideRepositoryRoot(absolutePath, repositoryRoot) {
    const resolvedRoot = node_path_1.default.resolve(repositoryRoot);
    const repositoryRootWithSeparator = resolvedRoot + node_path_1.default.sep;
    if (absolutePath !== resolvedRoot && !absolutePath.startsWith(repositoryRootWithSeparator)) {
        throw new Error("Artifact license reminder target must stay inside the repository root.");
    }
}
function isValidArtifactLicenseReminderManagedRegion(managedRegion) {
    const lines = normalizeManagedRegion(managedRegion).split("\n");
    if (lines.length !== 10) {
        return false;
    }
    if (lines[0] !== exports.ARTIFACT_LICENSE_REMINDER_START_MARKER ||
        lines[1] !== "```text" ||
        lines[8] !== "```" ||
        lines[9] !== exports.ARTIFACT_LICENSE_REMINDER_END_MARKER) {
        return false;
    }
    if (!isValidHorizontalBorder(lines[2]) || !isValidHorizontalBorder(lines[7])) {
        return false;
    }
    if (!isValidBoxLine(lines[3]) || !isValidBoxLine(lines[4]) ||
        !isValidBoxLine(lines[5]) || !isValidBoxLine(lines[6])) {
        return false;
    }
    if (boxLineContent(lines[5]) !== `Purchase: ${license_guidance_1.OFFICIAL_DAY_SHIFT_LICENSE_PURCHASE_URL}`) {
        return false;
    }
    const generatedDate = extractArtifactReminderGeneratedDate(managedRegion);
    return generatedDate !== null &&
        isValidDateOnly(generatedDate) &&
        boxLineContent(lines[6]) === `Generated: ${generatedDate}`;
}
function refreshReasonFromFreshStaleness(staleness) {
    if (staleness.reason === "fresh" ||
        staleness.reason === "exactly-thirty-days-old" ||
        staleness.reason === "future-generated-date") {
        return staleness.reason;
    }
    throw new Error("Valid managed license reminder regions must include valid generated metadata.");
}
function isValidHorizontalBorder(line) {
    if (line.length !== HORIZONTAL_BORDER_WIDTH) {
        return false;
    }
    return [...line].every((character) => exports.ARTIFACT_LICENSE_REMINDER_HORIZONTAL_BORDER_CHARACTERS.includes(character));
}
function isValidBoxLine(line) {
    return line.length === HORIZONTAL_BORDER_WIDTH &&
        line.startsWith("! ") &&
        line.endsWith(" !") &&
        /^[\x20-\x7E]+$/.test(line);
}
function boxLineContent(line) {
    return line.slice(2, -2).trimEnd();
}
function findExistingManagedRegion(markdownText) {
    const startIndexes = findAllIndexes(markdownText, exports.ARTIFACT_LICENSE_REMINDER_START_MARKER);
    const endIndexes = findAllIndexes(markdownText, exports.ARTIFACT_LICENSE_REMINDER_END_MARKER);
    if (startIndexes.length === 0 && endIndexes.length === 0) {
        return null;
    }
    if (startIndexes.length !== endIndexes.length) {
        throw new Error("Artifact markdown must contain exactly one complete managed license reminder marker pair.");
    }
    if (startIndexes.length !== 1 || endIndexes.length !== 1) {
        throw new Error("Artifact markdown must contain exactly one complete managed license reminder marker pair.");
    }
    if (startIndexes[0] > endIndexes[0]) {
        throw new Error("Artifact markdown managed license reminder markers are out of order.");
    }
    return {
        startIndex: startIndexes[0],
        endIndex: endIndexes[0] + exports.ARTIFACT_LICENSE_REMINDER_END_MARKER.length
    };
}
function findAllCompleteManagedRegions(markdownText) {
    const startIndexes = findAllIndexes(markdownText, exports.ARTIFACT_LICENSE_REMINDER_START_MARKER);
    const endIndexes = findAllIndexes(markdownText, exports.ARTIFACT_LICENSE_REMINDER_END_MARKER);
    if (startIndexes.length === 0 && endIndexes.length === 0) {
        return [];
    }
    if (startIndexes.length !== endIndexes.length) {
        throw new Error("Artifact markdown must contain complete managed license reminder marker pairs for cleanup.");
    }
    const regions = [];
    let previousEndIndex = -1;
    for (let index = 0; index < startIndexes.length; index += 1) {
        const startIndex = startIndexes[index];
        const endMarkerIndex = endIndexes[index];
        if (startIndex < previousEndIndex || startIndex > endMarkerIndex) {
            throw new Error("Artifact markdown managed license reminder markers are out of order.");
        }
        const endIndex = endMarkerIndex + exports.ARTIFACT_LICENSE_REMINDER_END_MARKER.length;
        regions.push({ startIndex, endIndex });
        previousEndIndex = endIndex;
    }
    return regions;
}
function normalizeManagedRegion(managedRegion) {
    const normalizedRegion = normalizeLineEndings(managedRegion).replace(/\n+$/g, "");
    const existingRegion = findExistingManagedRegion(normalizedRegion);
    if (existingRegion === null) {
        throw new Error("Managed license reminder region must include a complete marker pair.");
    }
    if (existingRegion.startIndex !== 0 || existingRegion.endIndex !== normalizedRegion.length) {
        throw new Error("Managed license reminder region must contain only the managed marker block.");
    }
    return normalizedRegion;
}
function listCleanupCandidateFiles(root) {
    const files = [];
    const stack = [root];
    while (stack.length > 0) {
        const directory = stack.pop();
        const entries = node_fs_1.default.readdirSync(directory, { withFileTypes: true });
        for (const entry of entries) {
            const absolutePath = node_path_1.default.join(directory, entry.name);
            if (entry.isDirectory()) {
                stack.push(absolutePath);
                continue;
            }
            if (!entry.isFile()) {
                continue;
            }
            if (entry.name === "LICENSE-REMINDER.md" || entry.name.endsWith(".md")) {
                files.push(absolutePath);
            }
        }
    }
    return files.sort();
}
function shouldDeleteCleanedFallbackReminderFile(absolutePath, cleanedMarkdown) {
    return node_path_1.default.basename(absolutePath) === "LICENSE-REMINDER.md" &&
        cleanedMarkdown.trim() === "";
}
function toRepositoryRelativePath(repositoryRoot, absolutePath) {
    const relativePath = node_path_1.default.relative(repositoryRoot, absolutePath);
    return relativePath.split(node_path_1.default.sep).join("/");
}
function compareCleanupOperations(left, right) {
    return left.path.localeCompare(right.path);
}
function findReminderInsertionIndex(markdownText) {
    const lines = markdownText.split("\n");
    const frontMatterClosingLine = findFrontMatterClosingLine(lines);
    if (frontMatterClosingLine !== null) {
        return countCharactersThroughLine(lines, frontMatterClosingLine);
    }
    const firstHeadingLine = lines.findIndex((line) => /^#{1,6}\s+/.test(line));
    if (firstHeadingLine >= 0) {
        return countCharactersBeforeLine(lines, firstHeadingLine);
    }
    return markdownText.length;
}
function findFrontMatterClosingLine(lines) {
    if (lines[0] !== "---") {
        return null;
    }
    const closingIndex = lines.findIndex((line, index) => index > 0 && line === "---");
    return closingIndex >= 0 ? closingIndex : null;
}
function insertManagedRegion(markdownText, insertionIndex, managedRegion) {
    const prefix = markdownText.slice(0, insertionIndex);
    const suffix = markdownText.slice(insertionIndex);
    const normalizedPrefix = prefix === "" || prefix.endsWith("\n") ? prefix : `${prefix}\n`;
    const normalizedSuffix = suffix === "" || suffix.startsWith("\n") ? suffix : `\n${suffix}`;
    return `${normalizedPrefix}${managedRegion}${normalizedSuffix}`;
}
function replaceManagedRegion(options) {
    return restoreLineEndings(placeArtifactLicenseReminder({
        markdownText: options.markdownText,
        managedRegion: options.managedRegion
    }), options.lineEnding);
}
function countCharactersBeforeLine(lines, lineIndex) {
    if (lineIndex <= 0) {
        return 0;
    }
    return lines.slice(0, lineIndex).join("\n").length + 1;
}
function countCharactersThroughLine(lines, lineIndex) {
    return countCharactersBeforeLine(lines, lineIndex + 1);
}
function findAllIndexes(text, search) {
    const indexes = [];
    let index = text.indexOf(search);
    while (index >= 0) {
        indexes.push(index);
        index = text.indexOf(search, index + search.length);
    }
    return indexes;
}
function detectLineEnding(text) {
    return text.includes("\r\n") ? "\r\n" : "\n";
}
function summaryIsEligibleForFallbackArtifactReminder(summary) {
    return summary.materialWrite &&
        !summary.dryRun &&
        (summary.jsonOnly !== true || summary.humanReadableStreamEnabled === true) &&
        summary.commandFamily !== "unknown" &&
        summary.commandFamily !== "future";
}
function selectFallbackArtifactLicenseReminderTarget(summary) {
    const fallbackTargetsByPath = new Map();
    for (const artifact of summary.updatedArtifacts) {
        if (!artifact.materialUpdate || artifact.isCoordinationArtifact) {
            continue;
        }
        const targetPath = deriveFallbackArtifactLicenseReminderTarget(artifact.path);
        if (targetPath !== null && !fallbackTargetsByPath.has(targetPath)) {
            fallbackTargetsByPath.set(targetPath, {
                sourcePath: artifact.path,
                targetPath
            });
        }
    }
    return [...fallbackTargetsByPath.values()].sort((a, b) => a.targetPath.localeCompare(b.targetPath) || a.sourcePath.localeCompare(b.sourcePath))[0] ?? null;
}
function deriveFallbackArtifactLicenseReminderTarget(artifactPath) {
    const parsedPath = (0, paths_1.parseRepositoryRelativePath)(artifactPath);
    if (!isInsideDayShiftPlanningRoot(parsedPath.segments)) {
        return null;
    }
    const fallbackDirectory = deriveFallbackArtifactLicenseReminderDirectory(parsedPath.segments);
    return `${fallbackDirectory}/LICENSE-REMINDER.md`;
}
function deriveFallbackArtifactLicenseReminderDirectory(segments) {
    const taskSegmentIndex = segments.lastIndexOf("tasks");
    if (taskSegmentIndex >= 0) {
        return segments.slice(0, taskSegmentIndex).join("/");
    }
    return node_path_1.default.posix.dirname(segments.join("/"));
}
function isInsideDayShiftPlanningRoot(segments) {
    return segments.length >= 3 &&
        segments[0] === ".day-shift" &&
        segments[1] === "planning";
}
function normalizeLineEndings(text) {
    return text.replace(/\r\n/g, "\n");
}
function restoreLineEndings(text, lineEnding) {
    return lineEnding === "\n" ? text : text.replace(/\n/g, "\r\n");
}
function compareArtifactReminderTargetClassifications(a, b) {
    return compareArtifactReminderTargetLayers(a.layer, b.layer) ||
        a.path.localeCompare(b.path);
}
function compareArtifactReminderTargetLayers(a, b) {
    return (ARTIFACT_REMINDER_TARGET_LAYER_ORDER.get(a) ?? Number.MAX_SAFE_INTEGER) -
        (ARTIFACT_REMINDER_TARGET_LAYER_ORDER.get(b) ?? Number.MAX_SAFE_INTEGER);
}
