/**
 * MCP Optimizer — Analyze and optimize MCP server configurations
 *
 * Reads .claude/settings.json (or .claude/settings.local.json),
 * detects unused MCP servers based on analytics,
 * estimates token savings per server, and generates recommendations.
 */

import { readFileSync, existsSync } from 'fs';
import { join } from 'path';

const SETTINGS_PATHS = [
  join(process.cwd(), '.claude/settings.local.json'),
  join(process.cwd(), '.claude/settings.json'),
  join(process.env.USERPROFILE || process.env.HOME || '', '.claude/settings.json')
];

// Estimated token overhead per MCP server in context window
const MCP_TOKEN_OVERHEAD = {
  default: 3000,    // average per server
  heavy: 8000,      // known heavy servers (filesystem, database)
  light: 1500       // known light servers (simple tools)
};

const HEAVY_SERVERS = ['filesystem', 'postgres', 'sqlite', 'mysql', 'mongodb'];
const LIGHT_SERVERS = ['time', 'echo', 'fetch'];

// ============================================================================
// Settings Loading
// ============================================================================

/**
 * Load Claude settings file
 * @returns {Object|null} Settings object or null
 */
export function loadClaudeSettings() {
  for (const path of SETTINGS_PATHS) {
    if (existsSync(path)) {
      try {
        return { settings: JSON.parse(readFileSync(path, 'utf8')), path };
      } catch {
        continue;
      }
    }
  }
  return null;
}

/**
 * Extract MCP server list from settings
 * @param {Object} settings - Claude settings object
 * @returns {Array} Array of { name, config } objects
 */
export function extractMCPServers(settings) {
  const servers = [];

  // Claude settings format: mcpServers: { name: { command, args, env } }
  if (settings.mcpServers) {
    for (const [name, config] of Object.entries(settings.mcpServers)) {
      servers.push({ name, config });
    }
  }

  return servers;
}

// ============================================================================
// Usage Analysis
// ============================================================================

/**
 * Detect unused MCP servers by checking analytics logs
 * @param {Array} servers - Array of MCP server descriptors
 * @param {number} [lookbackDays=30] - Days to look back in analytics
 * @returns {Array} servers with usage stats added
 */
export function detectUnusedServers(servers, lookbackDays = 30) {
  // Read analytics for MCP tool usage patterns
  const analyticsPath = join(process.cwd(), '.morph/analytics/threads-log.jsonl');
  const usedServerNames = new Set();

  if (existsSync(analyticsPath)) {
    try {
      const cutoff = new Date();
      cutoff.setDate(cutoff.getDate() - lookbackDays);

      const lines = readFileSync(analyticsPath, 'utf8').trim().split('\n').filter(Boolean);
      for (const line of lines) {
        try {
          const event = JSON.parse(line);
          if (event.timestamp && new Date(event.timestamp) > cutoff) {
            // Check for MCP tool references in event data
            const eventStr = JSON.stringify(event);
            for (const server of servers) {
              if (eventStr.includes(server.name)) {
                usedServerNames.add(server.name);
              }
            }
          }
        } catch {
          // Skip malformed lines
        }
      }
    } catch {
      // Analytics not available — mark all as unknown usage
    }
  }

  return servers.map(server => {
    const isHeavy = HEAVY_SERVERS.some(h => server.name.toLowerCase().includes(h));
    const isLight = LIGHT_SERVERS.some(l => server.name.toLowerCase().includes(l));
    const overhead = isHeavy ? MCP_TOKEN_OVERHEAD.heavy : isLight ? MCP_TOKEN_OVERHEAD.light : MCP_TOKEN_OVERHEAD.default;

    const usageSeen = usedServerNames.has(server.name);

    return {
      ...server,
      overhead,
      usageSeen,
      usageStatus: usedServerNames.size === 0 ? 'unknown' : (usageSeen ? 'used' : 'unused')
    };
  });
}

// ============================================================================
// Recommendations
// ============================================================================

/**
 * Analyze MCP configuration and generate optimization recommendations
 * @returns {Object} Analysis results with recommendations
 */
export function analyzeMCP() {
  const result = loadClaudeSettings();

  if (!result) {
    return {
      found: false,
      message: 'No Claude settings file found. Checked: .claude/settings.json and .claude/settings.local.json',
      servers: [],
      recommendations: []
    };
  }

  const { settings, path: settingsPath } = result;
  const servers = extractMCPServers(settings);

  if (servers.length === 0) {
    return {
      found: true,
      settingsPath,
      servers: [],
      totalOverhead: 0,
      recommendations: [],
      message: 'No MCP servers configured.'
    };
  }

  const analyzedServers = detectUnusedServers(servers);
  const totalOverhead = analyzedServers.reduce((sum, s) => sum + s.overhead, 0);

  const unusedServers = analyzedServers.filter(s => s.usageStatus === 'unused');
  const unusedOverhead = unusedServers.reduce((sum, s) => sum + s.overhead, 0);

  const recommendations = [];

  if (unusedServers.length > 0) {
    recommendations.push({
      type: 'disable_unused',
      title: `Disable ${unusedServers.length} unused MCP server(s)`,
      description: `${unusedServers.map(s => s.name).join(', ')} have not been used recently.`,
      estimatedSavings: unusedOverhead,
      servers: unusedServers.map(s => s.name),
      action: 'Remove from mcpServers in .claude/settings.json'
    });
  }

  const heavyServers = analyzedServers.filter(s => s.overhead >= MCP_TOKEN_OVERHEAD.heavy && s.usageStatus !== 'unused');
  if (heavyServers.length > 0) {
    recommendations.push({
      type: 'defer_heavy',
      title: `Consider deferring ${heavyServers.length} heavy MCP server(s)`,
      description: `${heavyServers.map(s => s.name).join(', ')} use significant context window space.`,
      estimatedSavings: heavyServers.reduce((sum, s) => sum + s.overhead, 0) / 2,
      servers: heavyServers.map(s => s.name),
      action: 'Only enable when needed for that specific task'
    });
  }

  return {
    found: true,
    settingsPath,
    servers: analyzedServers,
    totalServers: servers.length,
    totalOverhead,
    unusedCount: unusedServers.length,
    potentialSavings: unusedOverhead,
    recommendations: recommendations.sort((a, b) => b.estimatedSavings - a.estimatedSavings)
  };
}
