"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveAuthenticatedEnvironmentContext = resolveAuthenticatedEnvironmentContext;
exports.resolveOptionalEnvironmentContext = resolveOptionalEnvironmentContext;
exports.withEnvironment = withEnvironment;
exports.withPublicEnvironment = withPublicEnvironment;
const config_1 = require("./config");
const apiClient_1 = require("./apiClient");
const environment_1 = require("./environment");
const messages_1 = require("./messages");
const workspaceAuth_1 = require("./workspaceAuth");
const DEFAULT_PUBLIC_ENV = 'prod';
function normalizeRequestedEnv(value) {
    if (typeof value !== 'string') {
        return undefined;
    }
    const normalized = value.trim();
    return normalized.length > 0 ? normalized : undefined;
}
function resolveConfiguredEnvironment(envName, command, options) {
    if (!envName && options.requireAuth) {
        (0, messages_1.printConfigEnvironmentMissing)(command);
        process.exitCode = 1;
        return null;
    }
    const resolvedEnvName = envName ?? (options.allowDefaultPublicEnv ? DEFAULT_PUBLIC_ENV : undefined);
    const envConfig = (0, environment_1.resolveEnvironmentConfig)(resolvedEnvName);
    if (!envConfig) {
        const choices = (0, environment_1.formatEnvironmentList)();
        (0, messages_1.printUnknownEnvironment)(resolvedEnvName || '', choices, command);
        process.exitCode = 1;
        return null;
    }
    if (envConfig.allowInsecureRequests) {
        process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
    }
    return envConfig;
}
function buildContext(cfg, envConfig, account, workspaceAuth = null) {
    const token = account?.token ?? cfg.token ?? '';
    const client = (0, apiClient_1.createCliApiClient)({ baseUrl: envConfig.apiBase, token });
    const aiClient = (0, apiClient_1.createCliAiClient)({ baseUrl: envConfig.aiBase, token });
    return {
        client,
        aiClient,
        env: envConfig.name,
        envConfig,
        token,
        config: cfg,
        account,
        workspaceAuth,
    };
}
function buildLegacyAccountSession(cfg) {
    if (!cfg.token || !cfg.env) {
        return null;
    }
    return {
        username: cfg.currentUsername ?? '',
        env: cfg.env,
        token: cfg.token,
        updatedAt: '',
    };
}
async function migrateLegacyConfigIfNeeded(cfg, envConfig, command) {
    if ((0, config_1.getCurrentAccountSession)(cfg) || !cfg.token || !cfg.env) {
        return cfg;
    }
    const client = (0, apiClient_1.createCliApiClient)({ baseUrl: envConfig.apiBase, token: cfg.token });
    try {
        const data = await client.me();
        const username = typeof data.user?.username === 'string' ? data.user.username.trim() : '';
        if (!username) {
            (0, messages_1.printErrorWithHelp)('Could not migrate your existing Playdrop CLI session.', ['Run "playdrop auth login" to reauthenticate and rebuild your local account store.'], { command });
            process.exitCode = 1;
            return null;
        }
        return (0, config_1.migrateLegacySession)({
            username,
            env: envConfig.name,
            token: cfg.token,
        });
    }
    catch {
        (0, messages_1.printErrorWithHelp)('Could not migrate your existing Playdrop CLI session.', ['Run "playdrop auth login" to reauthenticate and rebuild your local account store.'], { command });
        process.exitCode = 1;
        return null;
    }
}
async function loadWorkspaceAwareConfig(command, options) {
    let cfg = (0, config_1.loadConfig)();
    let workspaceAuth = null;
    try {
        workspaceAuth = options.workspacePath ? (0, workspaceAuth_1.findWorkspaceAuthConfig)(options.workspacePath) : null;
    }
    catch (error) {
        if (error instanceof workspaceAuth_1.WorkspaceAuthConfigError) {
            (0, messages_1.printErrorWithHelp)(`Invalid .playdrop.json at ${error.filePath}.`, [
                'The file must be valid JSON.',
                'It must include a non-empty "ownerUsername" string.',
            ], { command });
            process.exitCode = 1;
            return null;
        }
        throw error;
    }
    if (workspaceAuth && !(0, config_1.getCurrentAccountSession)(cfg) && cfg.token && cfg.env) {
        const provisionalEnvConfig = resolveConfiguredEnvironment(cfg.env, command, {
            requireAuth: true,
            allowDefaultPublicEnv: false,
        });
        if (!provisionalEnvConfig) {
            return null;
        }
        const migrated = await migrateLegacyConfigIfNeeded(cfg, provisionalEnvConfig, command);
        if (!migrated) {
            return null;
        }
        cfg = migrated;
    }
    return { cfg, workspaceAuth };
}
function resolveWorkspaceSelectedAccount(cfg, currentAccount, workspaceAuth, requestedEnv) {
    const matchingSessions = (0, config_1.listAccountSessionsForUsername)(workspaceAuth.config.ownerUsername, cfg);
    const preferredEnv = normalizeRequestedEnv(requestedEnv) ?? workspaceAuth.config.env;
    if (preferredEnv) {
        return {
            account: (0, config_1.findAccountSession)(workspaceAuth.config.ownerUsername, preferredEnv, cfg),
            matchingSessions,
        };
    }
    if (matchingSessions.length === 1) {
        return {
            account: matchingSessions[0],
            matchingSessions,
        };
    }
    if (currentAccount && currentAccount.username === workspaceAuth.config.ownerUsername) {
        return {
            account: (0, config_1.findAccountSession)(workspaceAuth.config.ownerUsername, currentAccount.env, cfg),
            matchingSessions,
        };
    }
    return {
        account: null,
        matchingSessions,
    };
}
function resolveRequestedCurrentAccount(cfg, currentAccount, requestedEnv) {
    const preferredEnv = normalizeRequestedEnv(requestedEnv);
    if (!currentAccount) {
        return null;
    }
    if (!preferredEnv || currentAccount.env === preferredEnv) {
        return currentAccount;
    }
    return (0, config_1.findAccountSession)(currentAccount.username, preferredEnv, cfg);
}
async function resolveAuthenticatedEnvironment(command, actionLabel, options = {}) {
    const loaded = await loadWorkspaceAwareConfig(command, options);
    if (!loaded) {
        return null;
    }
    const { cfg, workspaceAuth } = loaded;
    const currentAccount = (0, config_1.getCurrentAccountSession)(cfg) ?? buildLegacyAccountSession(cfg);
    const selectedAccount = workspaceAuth
        ? resolveWorkspaceSelectedAccount(cfg, currentAccount, workspaceAuth, options.env).account
        : resolveRequestedCurrentAccount(cfg, currentAccount, options.env);
    if (!selectedAccount) {
        if (workspaceAuth) {
            const matchingSessions = (0, config_1.listAccountSessionsForUsername)(workspaceAuth.config.ownerUsername, cfg);
            const preferredEnv = normalizeRequestedEnv(options.env) ?? workspaceAuth.config.env;
            if (!preferredEnv && matchingSessions.length > 1) {
                (0, messages_1.printErrorWithHelp)(`This workspace is pinned to ${workspaceAuth.config.ownerUsername}, but that account is logged in on multiple environments.`, [
                    `Run "playdrop ${command} --env <env>" to target the matching workspace environment.`,
                    `Or run "playdrop auth use ${workspaceAuth.config.ownerUsername} --env <env>" to change your global default account.`,
                ], { command });
                process.exitCode = 1;
                return null;
            }
            const envSuffix = preferredEnv ? ` on ${preferredEnv}` : '';
            (0, messages_1.printErrorWithHelp)(`This workspace is pinned to ${workspaceAuth.config.ownerUsername}${envSuffix}, but that account is not logged in.`, [
                `Run "playdrop auth login${preferredEnv ? ` --env ${preferredEnv}` : ''}" while authenticated as ${workspaceAuth.config.ownerUsername}.`,
                'Or remove .playdrop.json if this workspace should use your current default account.',
            ], { command });
            process.exitCode = 1;
            return null;
        }
        const preferredEnv = normalizeRequestedEnv(options.env);
        if (currentAccount && preferredEnv) {
            (0, messages_1.printErrorWithHelp)(`${currentAccount.username} is not logged in on ${preferredEnv}.`, [
                `Run "playdrop auth login --env ${preferredEnv}" while authenticated as ${currentAccount.username}.`,
                `Or run "playdrop auth use <username> --env ${preferredEnv}" to switch accounts.`,
            ], { command });
            process.exitCode = 1;
            return null;
        }
        (0, messages_1.printLoginRequired)(actionLabel, command);
        process.exitCode = 1;
        return null;
    }
    const envConfig = resolveConfiguredEnvironment(selectedAccount.env, command, {
        requireAuth: true,
        allowDefaultPublicEnv: false,
    });
    if (!envConfig) {
        return null;
    }
    return {
        cfg: (0, config_1.loadConfig)(),
        account: selectedAccount,
        envConfig,
        workspaceAuth,
    };
}
async function resolveAuthenticatedEnvironmentContext(command, actionLabel, options = {}) {
    const resolved = await resolveAuthenticatedEnvironment(command, actionLabel, options);
    if (!resolved) {
        return null;
    }
    return buildContext(resolved.cfg, resolved.envConfig, resolved.account, resolved.workspaceAuth);
}
async function resolveOptionalEnvironmentContext(command, options = {}) {
    const loaded = await loadWorkspaceAwareConfig(command, options);
    if (!loaded) {
        return null;
    }
    const { cfg, workspaceAuth } = loaded;
    const currentAccount = (0, config_1.getCurrentAccountSession)(cfg) ?? buildLegacyAccountSession(cfg);
    if (!currentAccount && !workspaceAuth) {
        return null;
    }
    const selectedAccount = workspaceAuth
        ? resolveWorkspaceSelectedAccount(cfg, currentAccount, workspaceAuth, options.env).account
        : resolveRequestedCurrentAccount(cfg, currentAccount, options.env);
    if (!selectedAccount) {
        if (workspaceAuth) {
            const matchingSessions = (0, config_1.listAccountSessionsForUsername)(workspaceAuth.config.ownerUsername, cfg);
            const preferredEnv = normalizeRequestedEnv(options.env) ?? workspaceAuth.config.env;
            if (!preferredEnv && matchingSessions.length > 1) {
                (0, messages_1.printErrorWithHelp)(`This workspace is pinned to ${workspaceAuth.config.ownerUsername}, but that account is logged in on multiple environments.`, [
                    `Run "playdrop ${command} --env <env>" to target the matching workspace environment.`,
                    `Or run "playdrop auth use ${workspaceAuth.config.ownerUsername} --env <env>" to change your global default account.`,
                ], { command });
            }
            else {
                const envSuffix = preferredEnv ? ` on ${preferredEnv}` : '';
                (0, messages_1.printErrorWithHelp)(`This workspace is pinned to ${workspaceAuth.config.ownerUsername}${envSuffix}, but that account is not logged in.`, [
                    `Run "playdrop auth login${preferredEnv ? ` --env ${preferredEnv}` : ''}" while authenticated as ${workspaceAuth.config.ownerUsername}.`,
                    'Or remove .playdrop.json if this workspace should use your current default account.',
                ], { command });
            }
            process.exitCode = 1;
        }
        else if (currentAccount && normalizeRequestedEnv(options.env)) {
            const preferredEnv = normalizeRequestedEnv(options.env);
            (0, messages_1.printErrorWithHelp)(`${currentAccount.username} is not logged in on ${preferredEnv}.`, [
                `Run "playdrop auth login --env ${preferredEnv}" while authenticated as ${currentAccount.username}.`,
                `Or run "playdrop auth use <username> --env ${preferredEnv}" to switch accounts.`,
            ], { command });
            process.exitCode = 1;
        }
        return null;
    }
    const envConfig = resolveConfiguredEnvironment(selectedAccount.env, command, {
        requireAuth: true,
        allowDefaultPublicEnv: false,
    });
    if (!envConfig) {
        return null;
    }
    return buildContext((0, config_1.loadConfig)(), envConfig, selectedAccount, workspaceAuth);
}
async function withEnvironment(command, actionLabel, callback, options = {}) {
    const ctx = await resolveAuthenticatedEnvironmentContext(command, actionLabel, options);
    if (!ctx) {
        return;
    }
    await callback(ctx);
}
async function withPublicEnvironment(command, callback) {
    const cfg = (0, config_1.loadConfig)();
    const account = (0, config_1.getCurrentAccountSession)(cfg);
    const envConfig = resolveConfiguredEnvironment(account?.env ?? cfg.env, command, {
        requireAuth: false,
        allowDefaultPublicEnv: true,
    });
    if (!envConfig) {
        return;
    }
    await callback(buildContext(cfg, envConfig, account));
}
