import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
import { isAbsolute, join, resolve } from "path";
import { z } from "zod";
const SeaworkWorktreeMetadataV1Schema = z.object({
    version: z.literal(1),
    baseRefName: z.string().min(1),
});
const SeaworkWorktreeMetadataV2Schema = z.object({
    version: z.literal(2),
    baseRefName: z.string().min(1),
    runtime: z
        .object({
        worktreePort: z.number().int().positive(),
    })
        .optional(),
});
const SeaworkWorktreeMetadataSchema = z.union([
    SeaworkWorktreeMetadataV1Schema,
    SeaworkWorktreeMetadataV2Schema,
]);
function getGitDirForWorktreeRoot(worktreeRoot) {
    const gitPath = join(worktreeRoot, ".git");
    if (!existsSync(gitPath)) {
        throw new Error(`Not a git repository: ${worktreeRoot}`);
    }
    // In a worktree checkout, `.git` is a file containing `gitdir: <path>`.
    // In a normal checkout, `.git` is a directory.
    try {
        const gitFileContent = readFileSync(gitPath, "utf8");
        const match = gitFileContent.match(/gitdir:\s*(.+)/);
        if (match?.[1]) {
            const raw = match[1].trim();
            return isAbsolute(raw) ? raw : resolve(worktreeRoot, raw);
        }
    }
    catch {
        // If `.git` is a directory, readFileSync will throw; fall through.
    }
    return gitPath;
}
export function getSeaworkWorktreeMetadataPath(worktreeRoot) {
    const gitDir = getGitDirForWorktreeRoot(worktreeRoot);
    return join(gitDir, "seawork", "worktree.json");
}
export function normalizeBaseRefName(input) {
    const trimmed = input.trim();
    if (!trimmed) {
        throw new Error("Base branch is required");
    }
    if (trimmed.startsWith("origin/")) {
        return trimmed.slice("origin/".length);
    }
    return trimmed;
}
export function writeSeaworkWorktreeMetadata(worktreeRoot, options) {
    const baseRefName = normalizeBaseRefName(options.baseRefName);
    if (baseRefName === "HEAD") {
        throw new Error("Base branch cannot be HEAD");
    }
    if (baseRefName.includes("..") || baseRefName.includes("@{")) {
        throw new Error(`Invalid base branch: ${baseRefName}`);
    }
    if (!/^[0-9A-Za-z._/-]+$/.test(baseRefName)) {
        throw new Error(`Invalid base branch: ${baseRefName}`);
    }
    const metadataPath = getSeaworkWorktreeMetadataPath(worktreeRoot);
    mkdirSync(join(getGitDirForWorktreeRoot(worktreeRoot), "seawork"), { recursive: true });
    const metadata = { version: 1, baseRefName };
    writeFileSync(metadataPath, `${JSON.stringify(metadata, null, 2)}\n`, "utf8");
}
export function writeSeaworkWorktreeRuntimeMetadata(worktreeRoot, options) {
    if (!Number.isInteger(options.worktreePort) || options.worktreePort <= 0) {
        throw new Error(`Invalid worktree runtime port: ${options.worktreePort}`);
    }
    const current = readSeaworkWorktreeMetadata(worktreeRoot);
    if (!current) {
        throw new Error("Cannot persist worktree runtime metadata: missing base metadata");
    }
    const metadataPath = getSeaworkWorktreeMetadataPath(worktreeRoot);
    mkdirSync(join(getGitDirForWorktreeRoot(worktreeRoot), "seawork"), { recursive: true });
    const next = {
        version: 2,
        baseRefName: current.baseRefName,
        runtime: {
            worktreePort: options.worktreePort,
        },
    };
    writeFileSync(metadataPath, `${JSON.stringify(next, null, 2)}\n`, "utf8");
}
export function readSeaworkWorktreeMetadata(worktreeRoot) {
    const metadataPath = getSeaworkWorktreeMetadataPath(worktreeRoot);
    if (!existsSync(metadataPath)) {
        return null;
    }
    const parsed = JSON.parse(readFileSync(metadataPath, "utf8"));
    return SeaworkWorktreeMetadataSchema.parse(parsed);
}
export function requireSeaworkWorktreeBaseRefName(worktreeRoot) {
    const metadataPath = getSeaworkWorktreeMetadataPath(worktreeRoot);
    const metadata = readSeaworkWorktreeMetadata(worktreeRoot);
    if (!metadata) {
        throw new Error(`Missing Seawork worktree base metadata: ${metadataPath}`);
    }
    return metadata.baseRefName;
}
export function readSeaworkWorktreeRuntimePort(worktreeRoot) {
    const metadata = readSeaworkWorktreeMetadata(worktreeRoot);
    if (!metadata) {
        return null;
    }
    if (metadata.version === 2 && metadata.runtime?.worktreePort) {
        return metadata.runtime.worktreePort;
    }
    return null;
}
//# sourceMappingURL=worktree-metadata.js.map