"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runCleanupCommand = runCleanupCommand;
const promises_1 = require("node:fs/promises");
const control_plane_config_1 = require("../config/control-plane-config");
const command_1 = require("../core/command");
const service_manager_1 = require("../core/service-manager");
const branding_1 = require("../core/branding");
const service_state_1 = require("../core/service-state");
const paths_1 = require("../core/paths");
const catalog_1 = require("../i18n/catalog");
const locale_1 = require("./locale");
const prompts_1 = require("./prompts");
const provider_resolution_1 = require("../platform/provider-resolution");
const factory_1 = require("../platform/auth/factory");
const factory_2 = require("../platform/ticket-tracker/factory");
const factory_3 = require("../git/factory");
const factory_4 = require("../workspaces/factory");
async function runCleanupCommand(options, deps = {}) {
    if (options.workspaces) {
        return runWorkspaceCleanupCommand(options, deps);
    }
    const locale = await (0, locale_1.loadCommandLocale)(options.cwd);
    const liveService = await (0, service_state_1.getLiveServiceState)(options.homeDirectory);
    if (liveService) {
        throw new Error((0, catalog_1.translate)(locale, "cleanup.command.serviceRunning", {
            pid: liveService.pid,
        }));
    }
    if (!(await (0, prompts_1.confirmIfInteractive)(deps.prompter ?? (0, prompts_1.createCliPrompter)({ locale }), {
        label: (0, catalog_1.translate)(locale, "cleanup.command.confirm.localState"),
        onCanceled: () => console.log((0, catalog_1.translate)(locale, "cleanup.command.canceled")),
    }))) {
        return 1;
    }
    await unloadServiceDefinition(options.homeDirectory, deps, locale);
    await (0, promises_1.rm)((0, paths_1.getControlPlaneHomePath)(options.homeDirectory), {
        recursive: true,
        force: true,
    });
    await removeDefinitionFiles((0, service_manager_1.getKnownServiceDefinitionPaths)(options.homeDirectory));
    console.log((0, catalog_1.translate)(locale, "cleanup.command.removedLocalState"));
    return 0;
}
async function runWorkspaceCleanupCommand(options, deps) {
    const { config } = (0, provider_resolution_1.resolveSupportedProviders)(await (deps.loadConfig ?? control_plane_config_1.loadConfig)(options.cwd));
    const locale = config.i18n.defaultLanguage;
    if (!(await (0, prompts_1.confirmIfInteractive)(deps.prompter ?? (0, prompts_1.createCliPrompter)({ locale }), {
        label: (0, catalog_1.translate)(locale, "cleanup.command.confirm.workspaces"),
        onCanceled: () => console.log((0, catalog_1.translate)(locale, "cleanup.command.canceled")),
    }))) {
        return 1;
    }
    const authProvider = (0, factory_1.createAuthProvider)(config);
    const ticketTracker = deps.createTicketTracker?.() ??
        (await (0, factory_2.createTicketTrackerClient)(config, authProvider));
    const gitRepository = (0, factory_3.createGitRepositoryClient)(config, authProvider);
    const issueWorkspaceManager = (0, factory_4.createIssueWorkspaceManager)(config, gitRepository);
    const result = deps.cleanupClosedWorkspaces
        ? await deps.cleanupClosedWorkspaces({
            repositoryRoot: options.cwd,
            repositoryHost: config.repositoryHost,
            ticketTrackerRef: config.ticketTracker,
            ticketTracker: ticketTracker,
        })
        : await issueWorkspaceManager.cleanupClosedWorkspaces({
            repositoryRoot: options.cwd,
            repositoryHost: config.repositoryHost,
            ticketTrackerRef: config.ticketTracker,
            ticketTracker: ticketTracker,
        });
    console.log((0, catalog_1.translate)(locale, "cleanup.command.removedClosedWorkspaces", {
        count: result.removedPaths.length,
    }));
    for (const warning of result.warnings) {
        console.warn(warning);
    }
    return 0;
}
async function unloadServiceDefinition(homeDirectory, deps, locale) {
    const manager = await (0, service_manager_1.detectServiceManager)({
        ...(homeDirectory ? { homeDirectory } : {}),
        ...(deps.platform ? { platform: deps.platform } : {}),
        ...(deps.release ? { release: deps.release } : {}),
        ...(deps.env ? { env: deps.env } : {}),
        ...(deps.uid !== undefined ? { uid: deps.uid } : {}),
        locale,
        ...(deps.commandExists ? { commandExists: deps.commandExists } : {}),
        runCommand: deps.runCommand ?? command_1.runCommand,
    });
    const run = deps.runCommand ?? command_1.runCommand;
    if (!manager.supported) {
        return;
    }
    if (manager.kind === service_manager_1.SERVICE_MANAGER_KINDS.launchd) {
        await run({
            command: service_manager_1.SERVICE_MANAGER_COMMANDS.launchctl,
            args: ["bootout", manager.launchctlDomain, manager.definitionPath],
            allowNonZeroExit: true,
            timeoutMs: 30_000,
        });
        return;
    }
    await run({
        command: service_manager_1.SERVICE_MANAGER_COMMANDS.systemctl,
        args: ["--user", "disable", "--now", branding_1.SYSTEMD_UNIT_NAME],
        allowNonZeroExit: true,
        timeoutMs: 30_000,
    });
    await run({
        command: service_manager_1.SERVICE_MANAGER_COMMANDS.systemctl,
        args: ["--user", "daemon-reload"],
        allowNonZeroExit: true,
        timeoutMs: 30_000,
    });
}
async function removeDefinitionFiles(definitionPaths) {
    for (const definitionPath of definitionPaths) {
        await (0, promises_1.rm)(definitionPath, { force: true });
    }
}
