import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync, unlinkSync } from 'fs';
import { join } from 'path';
import { logger } from '../utils/logger.js';
import { summarizeError } from '../utils/error-display.js';
/**
 * ProfileManager - Save and load named SDK host config profiles.
 *
 * Profiles are stored as JSON files in the configured profile directory.
 * Only host-surface settings (display, provider, behavior categories) are saved;
 * permissions and API keys are never included.
 */
export class ProfileManager {
    profilesDir;
    lastTimestamp = 0;
    constructor(baseDir) {
        this.profilesDir = baseDir;
    }
    get storagePath() {
        return this.profilesDir;
    }
    /**
     * save - Persist a profile under the given name.
     * Overwrites an existing profile with the same name.
     */
    save(name, data) {
        if (!name || !name.trim())
            throw new Error('Profile name cannot be empty');
        mkdirSync(this.profilesDir, { recursive: true });
        const sanitizedName = this.sanitizeName(name);
        const filePath = join(this.profilesDir, `${sanitizedName}.json`);
        const record = {
            name: sanitizedName,
            timestamp: this.nextTimestamp(),
            display: data.display ?? {},
            provider: data.provider ?? {},
            behavior: data.behavior ?? {},
        };
        writeFileSync(filePath, JSON.stringify(record, null, 2), 'utf-8');
        logger.debug('ProfileManager: saved profile', { name: sanitizedName, filePath });
        return filePath;
    }
    /**
     * load - Load a profile by name. Returns the profile data or throws if not found.
     */
    load(name) {
        if (!name || !name.trim())
            throw new Error('Profile name cannot be empty');
        const sanitizedName = this.sanitizeName(name);
        const filePath = join(this.profilesDir, `${sanitizedName}.json`);
        if (!existsSync(filePath)) {
            throw new Error(`Profile not found: ${name}`);
        }
        try {
            const raw = readFileSync(filePath, 'utf-8');
            const record = JSON.parse(raw);
            return {
                timestamp: Number(record.timestamp ?? 0),
                data: {
                    display: record.display ?? {},
                    provider: record.provider,
                    behavior: record.behavior ?? {},
                },
            };
        }
        catch (e) {
            throw new Error(`Failed to parse profile "${name}": ${summarizeError(e)}`);
        }
    }
    /**
     * list - Return all saved profiles sorted by most recent first.
     */
    list() {
        if (!existsSync(this.profilesDir))
            return [];
        let files;
        try {
            files = readdirSync(this.profilesDir).filter(f => f.endsWith('.json'));
        }
        catch (err) {
            logger.warn('ProfileManager: failed to list profiles directory', { dir: this.profilesDir, error: summarizeError(err) });
            return [];
        }
        const profiles = [];
        for (const file of files) {
            const name = file.replace(/\.json$/, '');
            const filePath = join(this.profilesDir, file);
            let timestamp = 0;
            try {
                const raw = readFileSync(filePath, 'utf-8');
                const record = JSON.parse(raw);
                timestamp = Number(record.timestamp ?? 0);
            }
            catch (err) {
                logger.warn('ProfileManager: skipping unreadable profile file', { file, error: summarizeError(err) });
                continue;
            }
            profiles.push({ name, timestamp, filePath });
        }
        profiles.sort((a, b) => {
            if (b.timestamp !== a.timestamp)
                return b.timestamp - a.timestamp;
            return b.name.localeCompare(a.name);
        });
        return profiles;
    }
    nextTimestamp() {
        const now = Date.now();
        this.lastTimestamp = now > this.lastTimestamp ? now : this.lastTimestamp + 1;
        return this.lastTimestamp;
    }
    /**
     * delete - Remove a profile by name. Returns true if deleted, false if not found.
     */
    delete(name) {
        if (!name || !name.trim())
            return false;
        const sanitizedName = this.sanitizeName(name);
        const filePath = join(this.profilesDir, `${sanitizedName}.json`);
        if (!existsSync(filePath))
            return false;
        try {
            unlinkSync(filePath);
            return true;
        }
        catch (err) {
            logger.warn('ProfileManager: failed to delete profile', { filePath, error: summarizeError(err) });
            return false;
        }
    }
    /**
     * sanitizeName - Safe filename from profile name.
     */
    sanitizeName(name) {
        return name
            .toLowerCase()
            .replace(/\s+/g, '-')
            .replace(/[^a-z0-9_-]/g, '')
            .replace(/-+/g, '-')
            .replace(/^-+|-+$/g, '')
            || 'profile';
    }
}
