"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.inspectRegisteredRepo = inspectRegisteredRepo;
exports.inspectRegisteredRepoPrerequisites = inspectRegisteredRepoPrerequisites;
exports.inspectRegisteredRepoWithConfig = inspectRegisteredRepoWithConfig;
const promises_1 = require("node:fs/promises");
const node_path_1 = __importDefault(require("node:path"));
const control_plane_config_1 = require("../../config/control-plane-config");
const branding_1 = require("../../core/branding");
const remote_base_branch_1 = require("../../git/remote-base-branch");
const remote_base_branch_2 = require("../../git/remote-base-branch");
const catalog_1 = require("../../i18n/catalog");
const provider_errors_1 = require("../../platform/provider-errors");
const factory_1 = require("../../platform/auth/factory");
const provider_resolution_1 = require("../../platform/provider-resolution");
const cli_worker_launcher_1 = require("../../worker/cli-worker-launcher");
const runtime_1 = require("../../worker/runtime");
const auth_message_sanitizer_1 = require("../auth-message-sanitizer");
const shared_1 = require("../service/shared");
const tracked_project_1 = require("./tracked-project");
function isUnsupportedProviderFailure(error) {
    return (0, provider_errors_1.isUnsupportedProviderError)(error);
}
async function inspectRegisteredRepo(entry, lastResult, locale = catalog_1.DEFAULT_APP_LOCALE, options = {}) {
    const trackedProjectKey = (0, tracked_project_1.getEntryTrackedProjectKey)(entry);
    const identity = {
        trackedProjectKey,
        repositoryHost: entry.repositoryHost,
        ticketTracker: entry.ticketTracker,
        cwd: entry.cwd,
    };
    const preflight = await inspectRegisteredRepoPrerequisites(entry, lastResult, locale);
    if (preflight !== null) {
        return preflight;
    }
    try {
        const { config } = (0, provider_resolution_1.resolveSupportedProviders)(await (0, control_plane_config_1.loadConfig)(entry.cwd));
        return inspectRegisteredRepoWithConfig(entry, config, lastResult, locale, options);
    }
    catch (error) {
        if (isUnsupportedProviderFailure(error)) {
            throw error;
        }
        return {
            ...identity,
            state: shared_1.SERVICE_REPO_STATES.broken,
            lastResult,
            reason: error instanceof Error
                ? error.message
                : (0, catalog_1.translate)(locale, "service.runtime.configParseFailed", {
                    configFilename: branding_1.CONFIG_FILENAME,
                }),
        };
    }
}
async function inspectRegisteredRepoPrerequisites(entry, lastResult, locale = catalog_1.DEFAULT_APP_LOCALE) {
    const trackedProjectKey = (0, tracked_project_1.getEntryTrackedProjectKey)(entry);
    const identity = {
        trackedProjectKey,
        repositoryHost: entry.repositoryHost,
        ticketTracker: entry.ticketTracker,
        cwd: entry.cwd,
    };
    if (!entry.enabled) {
        return {
            ...identity,
            state: shared_1.SERVICE_REPO_STATES.disabled,
            lastResult,
        };
    }
    try {
        await (0, promises_1.access)(entry.cwd, promises_1.constants.F_OK);
    }
    catch {
        return {
            ...identity,
            state: shared_1.SERVICE_REPO_STATES.broken,
            lastResult,
            reason: (0, catalog_1.translate)(locale, "service.runtime.cwdMissing"),
        };
    }
    const configPath = node_path_1.default.join(entry.cwd, branding_1.CONFIG_FILENAME);
    try {
        await (0, promises_1.access)(configPath, promises_1.constants.F_OK);
    }
    catch {
        return {
            ...identity,
            state: shared_1.SERVICE_REPO_STATES.broken,
            lastResult,
            reason: (0, catalog_1.translate)(locale, "service.runtime.configMissing", {
                configFilename: branding_1.CONFIG_FILENAME,
            }),
        };
    }
    return null;
}
async function inspectRegisteredRepoWithConfig(entry, config, lastResult, locale, options = {}) {
    const trackedProjectKey = (0, tracked_project_1.getEntryTrackedProjectKey)(entry);
    const identity = {
        trackedProjectKey,
        repositoryHost: entry.repositoryHost,
        ticketTracker: entry.ticketTracker,
        cwd: entry.cwd,
    };
    if (options.useConfigLocale ?? true) {
        locale = config.i18n.defaultLanguage;
    }
    if ((0, provider_resolution_1.getTrackedProjectKey)(config) !== trackedProjectKey) {
        return {
            ...identity,
            state: shared_1.SERVICE_REPO_STATES.broken,
            lastResult,
            reason: (0, catalog_1.translate)(locale, "service.runtime.identityMismatch", {
                configFilename: branding_1.CONFIG_FILENAME,
            }),
        };
    }
    const remoteBaseBranch = await (0, remote_base_branch_1.checkRemoteBaseBranchRef)({
        cwd: entry.cwd,
        remoteName: config.repositoryHost.remoteName,
        baseBranch: config.repositoryHost.baseBranch,
        projectRef: config.repositoryHost.projectRef,
        credentials: await (0, remote_base_branch_2.tryResolveRemoteBaseBranchGitCredentials)((0, factory_1.createAuthProvider)(config), config.repositoryHost),
        locale,
    });
    if (remoteBaseBranch.kind !== "present") {
        return {
            ...identity,
            state: shared_1.SERVICE_REPO_STATES.broken,
            lastResult,
            reason: (0, auth_message_sanitizer_1.sanitizeAuthMessage)(remoteBaseBranch.message, locale),
        };
    }
    for (const worker of (0, control_plane_config_1.getConfiguredWorkerProviders)(config)) {
        try {
            await new cli_worker_launcher_1.CliWorkerLauncher((0, control_plane_config_1.isBuiltInWorkerName)(worker)
                ? worker
                : {
                    name: worker,
                    customWorker: (0, control_plane_config_1.resolveCustomWorkerConfig)(config, worker),
                    locale,
                }).ensureAvailable();
        }
        catch (error) {
            return {
                ...identity,
                state: shared_1.SERVICE_REPO_STATES.broken,
                lastResult,
                reason: error instanceof Error
                    ? error.message
                    : (0, catalog_1.translate)(locale, "service.runtime.workerUnavailable"),
            };
        }
    }
    if (options.validateWorkerRuntime) {
        try {
            await (0, runtime_1.createConfiguredWorkerRuntime)(config);
        }
        catch (error) {
            return {
                ...identity,
                state: shared_1.SERVICE_REPO_STATES.broken,
                lastResult,
                reason: (0, auth_message_sanitizer_1.sanitizeAuthMessage)(error instanceof Error
                    ? error.message
                    : (0, catalog_1.translate)(locale, "service.runtime.workerRuntimeInvalid"), locale),
            };
        }
    }
    return {
        ...identity,
        state: shared_1.SERVICE_REPO_STATES.healthy,
        lastResult,
    };
}
