"use strict";
/**
 * Create Command Handler
 *
 * Creates a new profile and prompts for login in an isolated Claude instance.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleCreate = void 0;
const child_process_1 = require("child_process");
const ui_1 = require("../../utils/ui");
const claude_detector_1 = require("../../utils/claude-detector");
const shell_executor_1 = require("../../utils/shell-executor");
const account_context_1 = require("../account-context");
const shared_resource_policy_1 = require("../shared-resource-policy");
const errors_1 = require("../../errors");
const exit_codes_1 = require("../../errors/exit-codes");
const types_1 = require("./types");
const create_command_env_1 = require("./create-command-env");
const config_loader_facade_1 = require("../../config/config-loader-facade");
function sanitizeProfileNameForInstance(name) {
    return name.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase();
}
/**
 * Handle the create command
 */
async function handleCreate(ctx, args) {
    await (0, ui_1.initUI)();
    const parsed = (0, types_1.parseArgs)(args);
    const { profileName, force, shareContext, contextGroup, deeperContinuity, bare } = parsed;
    (0, types_1.rejectUnsupportedAuthOptions)(parsed, {
        usage: 'ccs auth create <profile> [--force] [--bare] [--share-context] [--context-group <name>] [--deeper-continuity]',
    });
    if (!profileName) {
        console.log((0, ui_1.fail)('Profile name is required'));
        console.log('');
        console.log(`Usage: ${(0, ui_1.color)('ccs auth create <profile> [--force] [--bare] [--share-context] [--context-group <name>] [--deeper-continuity]', 'command')}`);
        console.log('');
        console.log('Example:');
        console.log(`  ${(0, ui_1.color)('ccs auth create work', 'command')}`);
        (0, errors_1.exitWithError)('Profile name is required', exit_codes_1.ExitCode.PROFILE_ERROR);
    }
    if (!(0, account_context_1.isValidAccountProfileName)(profileName)) {
        const error = 'Invalid profile name. Use letters/numbers/dash/underscore and start with a letter.';
        console.log((0, ui_1.fail)(error));
        console.log('');
        (0, errors_1.exitWithError)(error, exit_codes_1.ExitCode.PROFILE_ERROR);
    }
    // Check if profile already exists (check both legacy and unified)
    const existsLegacy = ctx.registry.hasProfile(profileName);
    const existsUnified = ctx.registry.hasAccountUnified(profileName);
    if (!force && (existsLegacy || existsUnified)) {
        console.log((0, ui_1.fail)(`Profile already exists: ${profileName}`));
        console.log(`    Use ${(0, ui_1.color)('--force', 'command')} to overwrite`);
        (0, errors_1.exitWithError)(`Profile already exists: ${profileName}`, exit_codes_1.ExitCode.PROFILE_ERROR);
    }
    const normalizedName = sanitizeProfileNameForInstance(profileName);
    const collidingName = Object.keys(ctx.registry.getAllProfilesMerged()).find((name) => name !== profileName && sanitizeProfileNameForInstance(name) === normalizedName);
    if (collidingName) {
        const error = `Profile "${profileName}" conflicts with existing profile "${collidingName}" on filesystem.`;
        console.log((0, ui_1.fail)(error));
        console.log('');
        (0, errors_1.exitWithError)(error, exit_codes_1.ExitCode.PROFILE_ERROR);
    }
    const resolvedContext = (0, account_context_1.resolveCreateAccountContext)({
        shareContext: !!shareContext,
        contextGroup,
        deeperContinuity: !!deeperContinuity,
    });
    if (resolvedContext.error) {
        console.log((0, ui_1.fail)(resolvedContext.error));
        console.log('');
        (0, errors_1.exitWithError)(resolvedContext.error, exit_codes_1.ExitCode.PROFILE_ERROR);
    }
    const contextPolicy = resolvedContext.policy;
    const contextMetadata = (0, account_context_1.policyToAccountContextMetadata)(contextPolicy);
    const useUnifiedConfig = (0, config_loader_facade_1.isUnifiedMode)();
    const profileExistedBeforeCreate = existsLegacy || existsUnified;
    const createdUnifiedProfile = useUnifiedConfig && !existsUnified;
    const createdLegacyProfile = !useUnifiedConfig && !existsLegacy;
    const previousLegacyProfile = existsLegacy
        ? ctx.registry.getProfile(profileName)
        : undefined;
    const previousUnifiedProfile = existsUnified
        ? ctx.registry.getAllAccountsUnified()[profileName]
        : undefined;
    const previousBare = (0, shared_resource_policy_1.isProfileLocalSharedResourceMode)(previousLegacyProfile) ||
        (0, shared_resource_policy_1.isProfileLocalSharedResourceMode)(previousUnifiedProfile);
    const effectiveBare = bare === true || (profileExistedBeforeCreate && previousBare);
    const resourceMetadata = effectiveBare ? (0, shared_resource_policy_1.sharedResourceModeToMetadata)('profile-local') : {};
    const previousContextPolicy = profileExistedBeforeCreate && (previousUnifiedProfile || previousLegacyProfile)
        ? (0, account_context_1.resolveAccountContextPolicy)(previousUnifiedProfile || previousLegacyProfile)
        : undefined;
    const claudeInfo = (0, claude_detector_1.getClaudeCliInfo)();
    if (!claudeInfo) {
        console.log((0, ui_1.fail)('Claude CLI not found'));
        console.log('');
        console.log('Please install Claude CLI first:');
        console.log(`  ${(0, ui_1.color)('https://claude.ai/download', 'path')}`);
        (0, errors_1.exitWithError)('Claude CLI not found', exit_codes_1.ExitCode.BINARY_ERROR);
    }
    let rollbackCompleted = false;
    const rollbackMetadata = () => {
        try {
            if (useUnifiedConfig) {
                if (createdUnifiedProfile) {
                    if (ctx.registry.hasAccountUnified(profileName)) {
                        ctx.registry.removeAccountUnified(profileName);
                    }
                }
                else if (previousUnifiedProfile) {
                    ctx.registry.updateAccountUnified(profileName, previousUnifiedProfile);
                }
            }
            else {
                if (createdLegacyProfile) {
                    if (ctx.registry.hasProfile(profileName)) {
                        ctx.registry.deleteProfile(profileName);
                    }
                }
                else if (previousLegacyProfile) {
                    ctx.registry.updateProfile(profileName, previousLegacyProfile);
                }
            }
        }
        catch {
            // Best-effort rollback to avoid leaving stale accounts after failed login.
        }
    };
    const rollbackFailedCreate = async () => {
        if (rollbackCompleted) {
            return;
        }
        rollbackCompleted = true;
        rollbackMetadata();
        if (!profileExistedBeforeCreate) {
            try {
                await ctx.instanceMgr.deleteInstance(profileName);
            }
            catch {
                // Best-effort cleanup.
            }
            return;
        }
        if (previousContextPolicy) {
            try {
                await ctx.instanceMgr.ensureInstance(profileName, previousContextPolicy, {
                    bare: previousBare,
                });
            }
            catch {
                // Best-effort rollback for context mode/group.
            }
        }
    };
    try {
        // Create instance directory
        console.log((0, ui_1.info)(`Creating profile: ${profileName}`));
        const instancePath = await ctx.instanceMgr.ensureInstance(profileName, contextPolicy, {
            bare: effectiveBare,
        });
        // Create/update profile entry based on config mode
        if (useUnifiedConfig) {
            // Use unified config (config.yaml)
            if (existsUnified) {
                ctx.registry.updateAccountUnified(profileName, {
                    context_mode: contextMetadata.context_mode,
                    context_group: contextMetadata.context_group,
                    ...resourceMetadata,
                });
                ctx.registry.touchAccountUnified(profileName);
            }
            else {
                ctx.registry.createAccountUnified(profileName, {
                    ...contextMetadata,
                    ...resourceMetadata,
                });
            }
        }
        else {
            // Use legacy profiles.json
            if (existsLegacy) {
                ctx.registry.updateProfile(profileName, {
                    type: 'account',
                    context_mode: contextMetadata.context_mode,
                    context_group: contextMetadata.context_group,
                    ...resourceMetadata,
                });
            }
            else {
                ctx.registry.createProfile(profileName, {
                    type: 'account',
                    context_mode: contextMetadata.context_mode,
                    context_group: contextMetadata.context_group,
                    ...resourceMetadata,
                });
            }
        }
        console.log((0, ui_1.info)(`Instance directory: ${instancePath}`));
        console.log('');
        const launchDescription = contextPolicy.mode === 'shared'
            ? contextPolicy.continuityMode === 'deeper'
                ? `Starting Claude with shared context group "${contextPolicy.group || 'default'}" (deeper continuity)...`
                : `Starting Claude with shared context group "${contextPolicy.group || 'default'}"...`
            : 'Starting Claude in isolated instance...';
        console.log((0, ui_1.warn)(launchDescription));
        console.log((0, ui_1.warn)('You will be prompted to login with your account.'));
        console.log('');
        const { path: claudeCli, needsShell } = claudeInfo;
        const childEnv = (0, create_command_env_1.stripAmbientProviderCredentials)((0, shell_executor_1.stripClaudeCodeEnv)({ ...process.env, CLAUDE_CONFIG_DIR: instancePath }));
        // Execute Claude in isolated instance (will auto-prompt for login if no credentials)
        // On Windows, .cmd/.bat/.ps1 files need shell: true to execute properly
        let child;
        try {
            if (needsShell) {
                const cmdString = (0, shell_executor_1.escapeShellArg)(claudeCli);
                child = (0, child_process_1.spawn)(cmdString, {
                    stdio: 'inherit',
                    windowsHide: true,
                    shell: (0, shell_executor_1.getWindowsEscapedCommandShell)(),
                    env: childEnv,
                });
            }
            else {
                child = (0, child_process_1.spawn)(claudeCli, [], {
                    stdio: 'inherit',
                    windowsHide: true,
                    env: childEnv,
                });
            }
        }
        catch (error) {
            await rollbackFailedCreate();
            (0, errors_1.exitWithError)(`Failed to execute Claude CLI: ${error.message}`, exit_codes_1.ExitCode.BINARY_ERROR);
        }
        child.on('exit', async (code) => {
            if (code === 0) {
                console.log('');
                console.log((0, ui_1.infoBox)(`Profile:  ${profileName}\n` +
                    `Instance: ${instancePath}\n` +
                    `Type:     account\n` +
                    `Context:  ${(0, account_context_1.formatAccountContextPolicy)(contextPolicy)}\n` +
                    `Tokens:   isolated per account\n` +
                    `Resources: ${effectiveBare ? 'profile-local (bare)' : 'shared with ~/.claude'}` +
                    (effectiveBare ? '\nMode:     bare (no shared symlinks)' : ''), 'Profile Created'));
                console.log('');
                console.log((0, ui_1.header)('Usage'));
                console.log(`  ${(0, ui_1.color)(`ccs ${profileName} "your prompt here"`, 'command')}`);
                console.log('');
                console.log('To keep two accounts separate, create another account and run either profile by name:');
                console.log(`  ${(0, ui_1.color)('ccs auth create personal', 'command')}`);
                console.log(`  ${(0, ui_1.color)(`ccs ${profileName}`, 'command')} / ${(0, ui_1.color)('ccs personal', 'command')}`);
                console.log('');
                console.log((0, ui_1.warnBox)(`Running the command below will SWITCH your default\n` +
                    `CCS account to "${profileName}". After this, running\n` +
                    `"ccs" without a profile name will use this account.\n\n` +
                    `  ${(0, ui_1.color)(`ccs auth default ${profileName}`, 'command')}\n\n` +
                    `To restore the original default, run:\n` +
                    `  ${(0, ui_1.color)('ccs auth reset-default', 'command')}`, 'Set as Default?'));
                console.log('');
                process.exit(0);
            }
            else {
                await rollbackFailedCreate();
                console.log('');
                console.log((0, ui_1.fail)('Login failed or cancelled'));
                console.log('');
                console.log('To retry:');
                console.log(`  ${(0, ui_1.color)(`ccs auth create ${profileName} --force`, 'command')}`);
                console.log('');
                (0, errors_1.exitWithError)('Login failed or cancelled', exit_codes_1.ExitCode.AUTH_ERROR);
            }
        });
        child.on('error', async (err) => {
            await rollbackFailedCreate();
            (0, errors_1.exitWithError)(`Failed to execute Claude CLI: ${err.message}`, exit_codes_1.ExitCode.BINARY_ERROR);
        });
    }
    catch (error) {
        await rollbackFailedCreate();
        (0, errors_1.exitWithError)(`Failed to create profile: ${error.message}`, exit_codes_1.ExitCode.GENERAL_ERROR);
    }
}
exports.handleCreate = handleCreate;
//# sourceMappingURL=create-command.js.map