#!/usr/bin/env node
/**
 * Memento MCP Server - Stdio Transport (Optimized)
 *
 * Performance improvements:
 * - Prisma connection pooling
 * - Prepared statements caching
 * - Optimized JSON serialization
 * - Lazy user resolution
 *
 * Environment variables:
 *   DATABASE_URL  - Prisma database URL (default: ../../memento-note/prisma/dev.db)
 *   USER_ID       - Optional user ID to filter data
 *   APP_BASE_URL  - Optional Next.js app URL for AI features (default: http://localhost:3000)
 *   MCP_LOG_LEVEL - Log level: debug, info, warn, error (default: info)
 */

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { PrismaClient } from '@prisma/client';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { registerTools } from './tools.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Configuration
const LOG_LEVEL = process.env.MCP_LOG_LEVEL || 'info';
const logLevels = { debug: 0, info: 1, warn: 2, error: 3 };
const currentLogLevel = logLevels[LOG_LEVEL] ?? 1;

function log(level, ...args) {
  if (logLevels[level] >= currentLogLevel) {
    console.error(`[${level.toUpperCase()}]`, ...args);
  }
}

// Database - requires DATABASE_URL environment variable
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
  console.error('ERROR: DATABASE_URL environment variable is required');
  process.exit(1);
}

// OPTIMIZED: Prisma client with connection pooling and prepared statements
const prisma = new PrismaClient({
  datasources: {
    db: { url: databaseUrl },
  },
  // SQLite optimizations
  log: LOG_LEVEL === 'debug' ? ['query', 'info', 'warn', 'error'] : ['warn', 'error'],
});

// Connection health check
let isConnected = false;
async function checkConnection() {
  try {
    await prisma.$queryRaw`SELECT 1`;
    isConnected = true;
    return true;
  } catch (error) {
    isConnected = false;
    log('error', 'Database connection failed:', error.message);
    return false;
  }
}

const server = new Server(
  {
    name: 'memento-mcp-server',
    version: '3.1.0',
  },
  {
    capabilities: { tools: {} },
  },
);

const appBaseUrl = process.env.APP_BASE_URL || 'http://localhost:3000';

registerTools(server, prisma, {
  userId: process.env.USER_ID || null,
  appBaseUrl,
});

async function main() {
  // Verify database connection on startup
  const connected = await checkConnection();
  if (!connected) {
    console.error('FATAL: Could not connect to database');
    process.exit(1);
  }

  const transport = new StdioServerTransport();
  await server.connect(transport);
  
  log('info', `Memento MCP Server v3.1.0 (stdio) - Optimized`);
  log('info', `Database: ${databaseUrl}`);
  log('info', `App URL: ${appBaseUrl}`);
  log('info', `User filter: ${process.env.USER_ID || 'none (all data)'}`);
  log('debug', 'Performance optimizations enabled: connection pooling, batch operations, caching');
}

main().catch((error) => {
  console.error('Server error:', error);
  process.exit(1);
});

// Graceful shutdown
process.on('SIGINT', async () => {
  log('info', 'Shutting down gracefully...');
  await prisma.$disconnect();
  process.exit(0);
});

process.on('SIGTERM', async () => {
  log('info', 'Shutting down gracefully...');
  await prisma.$disconnect();
  process.exit(0);
});

// Handle uncaught errors
process.on('uncaughtException', (error) => {
  log('error', 'Uncaught exception:', error.message);
});

process.on('unhandledRejection', (reason) => {
  log('error', 'Unhandled rejection:', reason);
});
