"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultIssueWorkspaceManager = void 0;
exports.getProjectWorkspaceRoot = getProjectWorkspaceRoot;
exports.getIssueWorkspacePath = getIssueWorkspacePath;
exports.buildIssueBranchName = buildIssueBranchName;
exports.resolveIssueBranchName = resolveIssueBranchName;
const promises_1 = require("node:fs/promises");
const node_path_1 = __importDefault(require("node:path"));
const branding_1 = require("../core/branding");
const paths_1 = require("../core/paths");
const tracked_project_1 = require("../core/tracked-project");
const catalog_1 = require("../i18n/catalog");
const provider_resolution_1 = require("../platform/provider-resolution");
const remote_url_1 = require("../platform/repository-host/remote-url");
const base_workspace_1 = require("./base-workspace");
class DefaultIssueWorkspaceManager {
    gitClient;
    authProvider;
    homeDirectory;
    locale;
    branchPrefix;
    constructor(gitClient, authProvider, homeDirectory, locale = catalog_1.DEFAULT_APP_LOCALE, branchPrefix = branding_1.CLI_COMMAND_NAME) {
        this.gitClient = gitClient;
        this.authProvider = authProvider;
        this.homeDirectory = homeDirectory;
        this.locale = locale;
        this.branchPrefix = branchPrefix;
    }
    async ensureWorkspace(input) {
        const workspacePath = getIssueWorkspacePath((0, tracked_project_1.toTrackedProjectRef)(input), input.issueId, this.homeDirectory);
        const existed = await directoryExists(workspacePath);
        await (0, promises_1.mkdir)(node_path_1.default.dirname(workspacePath), { recursive: true });
        const credentials = await this.authProvider.getGitCredentials(input.repositoryHost);
        await this.gitClient.ensureWorkspaceClone({
            remoteUrl: (0, remote_url_1.buildRepositoryHostRemoteUrl)(input.repositoryHost),
            workspacePath,
            baseBranch: input.baseBranch,
            credentials,
        });
        await this.gitClient.fetch(workspacePath);
        const branchName = input.branchName ??
            buildIssueBranchName(this.branchPrefix, input.issueId);
        await this.gitClient.checkoutIssueBranch({
            workspacePath,
            branchName,
            baseBranch: input.baseBranch,
        });
        return { path: workspacePath, branchName, existed };
    }
    async cleanupClosedWorkspaces(input) {
        const root = getProjectWorkspaceRoot((0, tracked_project_1.toTrackedProjectRef)({
            repositoryHost: input.repositoryHost,
            ticketTracker: input.ticketTrackerRef,
        }), this.homeDirectory);
        const removedPaths = [];
        const warnings = [];
        const workspaceIds = await listDirectoryNames(root);
        for (const issueId of workspaceIds) {
            if (issueId === base_workspace_1.BASE_WORKSPACES_DIRECTORY) {
                continue;
            }
            const workspacePath = node_path_1.default.join(root, issueId);
            try {
                if (await this.gitClient.hasChanges(workspacePath)) {
                    continue;
                }
                const issue = await input.ticketTracker.getIssueCleanupState(issueId);
                if (issue.isOpen) {
                    continue;
                }
                await (0, promises_1.rm)(workspacePath, { recursive: true, force: true });
                removedPaths.push(workspacePath);
            }
            catch (error) {
                warnings.push((0, catalog_1.translate)(this.locale, "workspace.cleanup.skipped", {
                    issueId,
                    workspacePath,
                    message: error instanceof Error
                        ? error.message
                        : (0, catalog_1.translate)(this.locale, "cli.command.unknownError"),
                }));
            }
        }
        return { removedPaths, warnings };
    }
}
exports.DefaultIssueWorkspaceManager = DefaultIssueWorkspaceManager;
function getProjectWorkspaceRoot(trackedProject, homeDirectory) {
    return node_path_1.default.join((0, paths_1.getControlPlaneHomePath)(homeDirectory), "workspaces", ...(0, provider_resolution_1.getTrackedProjectStorageSegments)(trackedProject));
}
function getIssueWorkspacePath(trackedProject, issueId, homeDirectory) {
    return node_path_1.default.join(getProjectWorkspaceRoot(trackedProject, homeDirectory), issueId);
}
function buildIssueBranchName(branchPrefix, issueId) {
    return `${branchPrefix}/issue-${issueId}`;
}
function resolveIssueBranchName(branchPrefix, issue) {
    const sourceBranchName = issue.sourceBranchName?.trim();
    return sourceBranchName || buildIssueBranchName(branchPrefix, issue.id);
}
async function directoryExists(directoryPath) {
    try {
        const stat = await (0, promises_1.readdir)(directoryPath);
        return Array.isArray(stat);
    }
    catch {
        return false;
    }
}
async function listDirectoryNames(directoryPath) {
    try {
        return await (0, promises_1.readdir)(directoryPath);
    }
    catch {
        return [];
    }
}
