import path from "node:path";
import { existsSync, readFileSync } from "fs";
const GITHUB_REPO = "earendil-works/pi";
const CHANGELOG_LINK_BASE_PATH = "packages/coding-agent";
const LEGACY_REPO_RE = /^https:\/\/github\.com\/(?:badlogic|earendil-works)\/pi-mono(?=\/|$)/;
const URL_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
const INLINE_MARKDOWN_LINK_RE = /(!?\[[^\]\n]+\]\()([^\s)]+)((?:\s+[^)]*)?\))/g;
function entryVersion(entry) {
    return `${entry.major}.${entry.minor}.${entry.patch}`;
}
function normalizeTag(version) {
    const versionString = typeof version === "string" ? version : entryVersion(version);
    return versionString.startsWith("v") ? versionString : `v${versionString}`;
}
function splitLocalTarget(target) {
    const hashIndex = target.indexOf("#");
    const beforeHash = hashIndex === -1 ? target : target.slice(0, hashIndex);
    const fragment = hashIndex === -1 ? "" : target.slice(hashIndex);
    const queryIndex = beforeHash.indexOf("?");
    if (queryIndex === -1) {
        return { fragment, pathPart: beforeHash, query: "" };
    }
    return {
        fragment,
        pathPart: beforeHash.slice(0, queryIndex),
        query: beforeHash.slice(queryIndex),
    };
}
function normalizePathPart(value) {
    return value.replaceAll("\\", "/");
}
function resolveRepositoryPath(targetPath) {
    const normalizedTarget = normalizePathPart(targetPath);
    const joined = normalizedTarget.startsWith("/")
        ? path.posix.normalize(normalizedTarget.replace(/^\/+/, ""))
        : path.posix.normalize(path.posix.join(CHANGELOG_LINK_BASE_PATH, normalizedTarget));
    if (joined === "." || joined.startsWith("../") || joined === "..") {
        return undefined;
    }
    return joined;
}
function isDirectoryTarget(originalPath, repositoryPath) {
    if (originalPath.endsWith("/")) {
        return true;
    }
    const basename = path.posix.basename(repositoryPath);
    return !basename.includes(".");
}
function normalizeChangelogLinkTarget(target, tag) {
    let canonicalTarget = target.replace(LEGACY_REPO_RE, `https://github.com/${GITHUB_REPO}`);
    const repoUrl = `https://github.com/${GITHUB_REPO}`;
    for (const route of ["blob", "tree"]) {
        for (const branch of ["main", "master"]) {
            const floatingRefPrefix = `${repoUrl}/${route}/${branch}/`;
            if (canonicalTarget.startsWith(floatingRefPrefix)) {
                canonicalTarget = `${repoUrl}/${route}/${tag}/${canonicalTarget.slice(floatingRefPrefix.length)}`;
            }
        }
    }
    if (canonicalTarget.startsWith("#") || canonicalTarget.startsWith("//") || URL_SCHEME_RE.test(canonicalTarget)) {
        return canonicalTarget;
    }
    const { fragment, pathPart, query } = splitLocalTarget(canonicalTarget);
    if (!pathPart) {
        return canonicalTarget;
    }
    const repositoryPath = resolveRepositoryPath(pathPart);
    if (!repositoryPath) {
        return canonicalTarget;
    }
    const route = isDirectoryTarget(pathPart, repositoryPath) ? "tree" : "blob";
    return `https://github.com/${GITHUB_REPO}/${route}/${tag}/${encodeURI(repositoryPath)}${query}${fragment}`;
}
export function normalizeChangelogLinks(markdown, version) {
    const tag = normalizeTag(version);
    return markdown.replace(INLINE_MARKDOWN_LINK_RE, (_match, prefix, target, suffix) => {
        return `${prefix}${normalizeChangelogLinkTarget(target, tag)}${suffix}`;
    });
}
/**
 * Parse changelog entries from CHANGELOG.md
 * Scans for ## lines and collects content until next ## or EOF
 */
export function parseChangelog(changelogPath) {
    if (!existsSync(changelogPath)) {
        return [];
    }
    try {
        const content = readFileSync(changelogPath, "utf-8");
        const lines = content.split("\n");
        const entries = [];
        let currentLines = [];
        let currentVersion = null;
        for (const line of lines) {
            // Check if this is a version header (## [x.y.z] ...)
            if (line.startsWith("## ")) {
                // Save previous entry if exists
                if (currentVersion && currentLines.length > 0) {
                    entries.push({
                        ...currentVersion,
                        content: currentLines.join("\n").trim(),
                    });
                }
                // Try to parse version from this line
                const versionMatch = line.match(/##\s+\[?(\d+)\.(\d+)\.(\d+)\]?/);
                if (versionMatch) {
                    currentVersion = {
                        major: Number.parseInt(versionMatch[1], 10),
                        minor: Number.parseInt(versionMatch[2], 10),
                        patch: Number.parseInt(versionMatch[3], 10),
                    };
                    currentLines = [line];
                }
                else {
                    // Reset if we can't parse version
                    currentVersion = null;
                    currentLines = [];
                }
            }
            else if (currentVersion) {
                // Collect lines for current version
                currentLines.push(line);
            }
        }
        // Save last entry
        if (currentVersion && currentLines.length > 0) {
            entries.push({
                ...currentVersion,
                content: currentLines.join("\n").trim(),
            });
        }
        return entries;
    }
    catch (error) {
        console.error(`Warning: Could not parse changelog: ${error}`);
        return [];
    }
}
/**
 * Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
 */
export function compareVersions(v1, v2) {
    if (v1.major !== v2.major)
        return v1.major - v2.major;
    if (v1.minor !== v2.minor)
        return v1.minor - v2.minor;
    return v1.patch - v2.patch;
}
/**
 * Get entries newer than lastVersion
 */
export function getNewEntries(entries, lastVersion) {
    // Parse lastVersion
    const parts = lastVersion.split(".").map(Number);
    const last = {
        major: parts[0] || 0,
        minor: parts[1] || 0,
        patch: parts[2] || 0,
        content: "",
    };
    return entries.filter((entry) => compareVersions(entry, last) > 0);
}
// Re-export getChangelogPath from paths.ts for convenience
export { getChangelogPath } from "../config.js";
//# sourceMappingURL=changelog.js.map