/**
 * ClamAV Toggle Manager
 * Admin enable/disable control for antivirus scanning with full audit trail.
 * Toggle state is persisted in logs/clamav-toggle.json.
 */

import fs from 'fs';
import path from 'path';

// ── Types ──

interface ToggleHistoryEntry {
    timestamp: string;
    enabled: boolean;
    changedBy: string;
    reason: string;
}

interface ToggleState {
    enabled: boolean;
    lastChanged: string;
    changedBy: string;
    reason: string;
    history: ToggleHistoryEntry[];
}

// ── Configuration ──

const LOGS_DIR = path.resolve(process.cwd(), 'logs');
const TOGGLE_FILE = path.join(LOGS_DIR, 'clamav-toggle.json');
const MAX_HISTORY_ENTRIES = 100;

// ── In-memory cache ──

let cachedState: ToggleState | null = null;

// ── Functions ──

/**
 * Initialize the toggle file with default state (enabled)
 */
export function initializeToggleFile(): void {
    try {
        // Ensure logs directory exists
        if (!fs.existsSync(LOGS_DIR)) {
            fs.mkdirSync(LOGS_DIR, { recursive: true });
        }

        // If toggle file exists, load it into cache
        if (fs.existsSync(TOGGLE_FILE)) {
            const data = fs.readFileSync(TOGGLE_FILE, 'utf-8');
            cachedState = JSON.parse(data);
            console.log(`[ClamAV Toggle] Loaded state: enabled=${cachedState?.enabled}`);
            return;
        }

        // Create default toggle state
        const defaultState: ToggleState = {
            enabled: true,
            lastChanged: new Date().toISOString(),
            changedBy: 'system',
            reason: 'Initial setup',
            history: [
                {
                    timestamp: new Date().toISOString(),
                    enabled: true,
                    changedBy: 'system',
                    reason: 'Initial setup',
                },
            ],
        };

        fs.writeFileSync(TOGGLE_FILE, JSON.stringify(defaultState, null, 2));
        cachedState = defaultState;
        console.log('[ClamAV Toggle] Initialized with default state (enabled)');
    } catch (error) {
        console.error('[ClamAV Toggle] Failed to initialize:', error);
        // Default to enabled if we can't read the file
        cachedState = {
            enabled: true,
            lastChanged: new Date().toISOString(),
            changedBy: 'system',
            reason: 'Fallback default',
            history: [],
        };
    }
}

/**
 * Get current toggle status
 */
export function getToggleStatus(): { enabled: boolean; lastChanged: string; changedBy: string; reason: string } {
    if (!cachedState) {
        initializeToggleFile();
    }

    return {
        enabled: cachedState?.enabled ?? true,
        lastChanged: cachedState?.lastChanged ?? new Date().toISOString(),
        changedBy: cachedState?.changedBy ?? 'system',
        reason: cachedState?.reason ?? 'Default',
    };
}

/**
 * Set toggle status with audit trail
 */
export function setToggleStatus(
    enabled: boolean,
    userId: string,
    reason: string
): { success: boolean; state: ToggleState } {
    if (!cachedState) {
        initializeToggleFile();
    }

    const now = new Date().toISOString();

    // Add to history
    const historyEntry: ToggleHistoryEntry = {
        timestamp: now,
        enabled,
        changedBy: userId,
        reason,
    };

    cachedState = {
        enabled,
        lastChanged: now,
        changedBy: userId,
        reason,
        history: [
            historyEntry,
            ...(cachedState?.history || []),
        ].slice(0, MAX_HISTORY_ENTRIES),
    };

    // Persist to disk
    try {
        if (!fs.existsSync(LOGS_DIR)) {
            fs.mkdirSync(LOGS_DIR, { recursive: true });
        }
        fs.writeFileSync(TOGGLE_FILE, JSON.stringify(cachedState, null, 2));
    } catch (error) {
        console.error('[ClamAV Toggle] Failed to persist toggle state:', error);
    }

    console.log(`[ClamAV Toggle] Changed to enabled=${enabled} by ${userId}: ${reason}`);

    return { success: true, state: cachedState };
}

/**
 * Get toggle change history
 */
export function getToggleHistory(limit: number = 50): ToggleHistoryEntry[] {
    if (!cachedState) {
        initializeToggleFile();
    }

    return (cachedState?.history || []).slice(0, limit);
}
