import * as fs from 'fs';
import * as path from 'path';
import type { AdapterTemplate } from '../types';

/**
 * AWS Lambda adapter - serverless deployment on AWS Lambda.
 * Compiles to ESM, bundles with rspack to CJS for maximum compatibility.
 *
 * Prerequisites:
 *   npm install @codegenie/serverless-express
 *
 * The build process:
 * 1. TypeScript compiles to ESM in dist/
 * 2. serverless-setup.js is generated (sets FRONTMCP_SERVERLESS=1)
 * 3. index.js imports setup first, then main module
 * 4. rspack bundles everything into handler.cjs
 *
 * @see https://github.com/codegenie/serverless-express
 */
export const lambdaAdapter: AdapterTemplate = {
  // #368 round-3 — switched from 'esnext' to 'commonjs' for the same reason
  // as the vercel adapter: strict-ESM rspack rejects TS-emitted extensionless
  // relative imports, and the `byDependency.fullySpecified: false` workaround
  // didn't suppress it reliably. Lambda's Node runtime accepts CJS handlers,
  // and the bundled output is a CJS `handler.cjs` either way.
  moduleFormat: 'commonjs',
  shouldBundle: true,
  bundleOutput: 'handler.cjs',

  getSetupTemplate: () => `// Serverless environment setup - MUST be required first
// This sets FRONTMCP_SERVERLESS before any decorators run
process.env.FRONTMCP_SERVERLESS = '1';
process.env.FRONTMCP_DEPLOYMENT_MODE = 'serverless';
`,

  getEntryTemplate: (mainModulePath: string) => `// Auto-generated AWS Lambda entry point
// Generated by: frontmcp build --target lambda
//
// IMPORTANT: This adapter requires @codegenie/serverless-express
// Install it with: npm install @codegenie/serverless-express
//
require('./serverless-setup.js');
require('${mainModulePath}');
const { getServerlessHandlerAsync } = require('@frontmcp/sdk');
const serverlessExpressMod = require('@codegenie/serverless-express');
const serverlessExpress = serverlessExpressMod.default || serverlessExpressMod;

let serverlessExpressInstance = null;

async function setup() {
  const app = await getServerlessHandlerAsync();
  serverlessExpressInstance = serverlessExpress({ app });
}

exports.handler = async (event, context) => {
  if (!serverlessExpressInstance) {
    await setup();
  }
  return serverlessExpressInstance(event, context);
};
`,

  // #368 round-2 — `@codegenie/serverless-express` is a peer dep on this
  // adapter (the lambda runtime ships it via Layer or the user installs it).
  // The bundler externalizes it so rspack doesn't try to bundle it; this
  // validate hook surfaces a clear error at build time when the package
  // isn't installed locally either, instead of letting the user discover
  // a runtime "Cannot find module" error in CloudWatch logs.
  validate: () => {
    try {
      // Walk node_modules from cwd upward so monorepos / hoisted layouts work.
      let dir = process.cwd();
      const root = path.parse(dir).root;
      while (dir !== root) {
        const pkg = path.join(dir, 'node_modules', '@codegenie', 'serverless-express', 'package.json');
        if (fs.existsSync(pkg)) return;
        const next = path.dirname(dir);
        if (next === dir) break;
        dir = next;
      }
    } catch {
      // Fall through to throw — accessibility errors mean we can't verify presence.
    }
    throw new Error(
      `[--target lambda] missing required peer dependency @codegenie/serverless-express.\n` +
        `  Install it in your project:\n` +
        `    npm install @codegenie/serverless-express\n` +
        `  (or use a Lambda Layer that provides it).`,
    );
  },

  // No config file - user manages serverless.yml, SAM template, or CDK
};
