"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProfileManager = void 0;
const fs = __importStar(require("node:fs"));
const path = __importStar(require("node:path"));
const node_os_1 = require("node:os");
const FILES_TO_MIGRATE = [
    'clusters.json',
    'nodes.json',
    'operations.json',
    'firewalls.json',
    'vnets.json',
    'config.json',
    '.key',
];
const DIRS_TO_MIGRATE = ['ca', 'logs'];
/**
 * Manages CLI profiles (contexts) for multi-environment support.
 * Profiles are stored under ~/.flui/profiles/<name>/.
 * The active profile is stored in ~/.flui/context.
 *
 * Override active profile at runtime with FLUI_PROFILE env var.
 */
class ProfileManager {
    /**
     * Returns the currently active profile name.
     * Priority: FLUI_PROFILE env var > ~/.flui/context file > 'default'
     */
    static getActiveProfile() {
        if (process.env.FLUI_PROFILE) {
            return process.env.FLUI_PROFILE;
        }
        if (fs.existsSync(ProfileManager.CONTEXT_FILE)) {
            const content = fs
                .readFileSync(ProfileManager.CONTEXT_FILE, 'utf-8')
                .trim();
            if (content) {
                return content;
            }
        }
        return ProfileManager.DEFAULT_PROFILE;
    }
    /**
     * Sets the active profile in ~/.flui/context.
     * Does not validate that the profile exists — callers should check first.
     */
    static setActiveProfile(name) {
        ProfileManager.ensureBaseDir();
        fs.writeFileSync(ProfileManager.CONTEXT_FILE, name, {
            encoding: 'utf-8',
            mode: 0o600,
        });
    }
    /**
     * Returns the directory path for a given profile.
     * If no profile is specified, uses the active profile.
     */
    static getProfileDir(profile) {
        const active = profile ?? ProfileManager.getActiveProfile();
        return path.join(ProfileManager.PROFILES_DIR, active);
    }
    /**
     * Returns all existing profile names (directory names under ~/.flui/profiles/).
     */
    static listProfiles() {
        if (!fs.existsSync(ProfileManager.PROFILES_DIR)) {
            return [];
        }
        return fs
            .readdirSync(ProfileManager.PROFILES_DIR, { withFileTypes: true })
            .filter((entry) => entry.isDirectory())
            .map((entry) => entry.name)
            .sort((a, b) => a.localeCompare(b));
    }
    /**
     * Returns true if a profile directory exists.
     */
    static profileExists(name) {
        return fs.existsSync(path.join(ProfileManager.PROFILES_DIR, name));
    }
    /**
     * Creates a new profile directory with secure permissions.
     * Throws if the profile already exists.
     */
    static createProfile(name) {
        ProfileManager.validateProfileName(name);
        const profileDir = path.join(ProfileManager.PROFILES_DIR, name);
        if (fs.existsSync(profileDir)) {
            throw new Error(`Profile '${name}' already exists`);
        }
        fs.mkdirSync(profileDir, { recursive: true, mode: 0o700 });
    }
    /**
     * Deletes a profile directory.
     * Throws if trying to delete the default profile or a non-existent profile.
     */
    static deleteProfile(name) {
        if (name === ProfileManager.DEFAULT_PROFILE) {
            throw new Error(`Cannot delete the '${ProfileManager.DEFAULT_PROFILE}' profile`);
        }
        const profileDir = path.join(ProfileManager.PROFILES_DIR, name);
        if (!fs.existsSync(profileDir)) {
            throw new Error(`Profile '${name}' does not exist`);
        }
        fs.rmSync(profileDir, { recursive: true, force: true });
    }
    /**
     * Migrates legacy ~/.flui/ flat layout to ~/.flui/profiles/default/.
     *
     * Runs automatically on first launch after upgrade. Idempotent:
     * if ~/.flui/profiles/ already exists, does nothing.
     */
    static migrateIfNeeded() {
        // If profiles dir already exists, migration already done
        if (fs.existsSync(ProfileManager.PROFILES_DIR)) {
            return;
        }
        // Check if there is anything to migrate
        const hasData = FILES_TO_MIGRATE.some((f) => fs.existsSync(path.join(ProfileManager.BASE_DIR, f)));
        // Create profiles dir regardless (needed for future profiles)
        fs.mkdirSync(ProfileManager.PROFILES_DIR, { recursive: true, mode: 0o700 });
        const defaultDir = path.join(ProfileManager.PROFILES_DIR, ProfileManager.DEFAULT_PROFILE);
        fs.mkdirSync(defaultDir, { recursive: true, mode: 0o700 });
        if (!hasData) {
            return;
        }
        // Copy files
        for (const file of FILES_TO_MIGRATE) {
            const src = path.join(ProfileManager.BASE_DIR, file);
            if (fs.existsSync(src)) {
                fs.copyFileSync(src, path.join(defaultDir, file));
                fs.unlinkSync(src);
            }
        }
        // Copy directories
        for (const dir of DIRS_TO_MIGRATE) {
            const src = path.join(ProfileManager.BASE_DIR, dir);
            if (fs.existsSync(src)) {
                ProfileManager.copyDirSync(src, path.join(defaultDir, dir));
                fs.rmSync(src, { recursive: true, force: true });
            }
        }
    }
    static ensureBaseDir() {
        if (!fs.existsSync(ProfileManager.BASE_DIR)) {
            fs.mkdirSync(ProfileManager.BASE_DIR, { recursive: true, mode: 0o700 });
        }
    }
    static validateProfileName(name) {
        if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
            throw new Error(`Invalid profile name '${name}'. Only alphanumeric characters, hyphens, and underscores are allowed.`);
        }
    }
    static copyDirSync(src, dest) {
        if (!fs.existsSync(dest)) {
            fs.mkdirSync(dest, { recursive: true, mode: 0o700 });
        }
        for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
            const srcPath = path.join(src, entry.name);
            const destPath = path.join(dest, entry.name);
            if (entry.isDirectory()) {
                ProfileManager.copyDirSync(srcPath, destPath);
            }
            else {
                fs.copyFileSync(srcPath, destPath);
            }
        }
    }
}
exports.ProfileManager = ProfileManager;
ProfileManager.BASE_DIR = path.join((0, node_os_1.homedir)(), '.flui');
ProfileManager.PROFILES_DIR = path.join(ProfileManager.BASE_DIR, 'profiles');
ProfileManager.CONTEXT_FILE = path.join(ProfileManager.BASE_DIR, 'context');
ProfileManager.DEFAULT_PROFILE = 'default';
