import { readFile, writeFile } from 'node:fs/promises';
import { dirname, join, resolve } from 'node:path';
import process from 'node:process';
import { fileURLToPath } from 'node:url';
import { log } from 'node:console';
import { format, resolveConfig } from 'prettier';
import { ALL_TOOLS } from '../dist/tools/index.js';

const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const manifestPath = join(rootDir, 'mcpb/remnote-local/manifest.json');
const fallbackToolsPath = join(rootDir, 'mcpb/remnote-local/server/fallback-tools.generated.js');
const checkMode = process.argv.includes('--check');
const prettierOptions = (await resolveConfig(fallbackToolsPath)) ?? {};

const canonicalTools = ALL_TOOLS.map((tool) => ({
  name: tool.name,
  description: tool.description,
  inputSchema: tool.inputSchema,
}));

const manifestTools = canonicalTools.map(({ name, description }) => ({ name, description }));
const fallbackTools = canonicalTools.map(({ name, description, inputSchema }) => ({
  name,
  description,
  inputSchema,
}));

const currentManifest = JSON.parse(await readFile(manifestPath, 'utf8'));
const nextManifest = await format(JSON.stringify({ ...currentManifest, tools: manifestTools }), {
  ...prettierOptions,
  parser: 'json',
});
const nextFallbackTools = await format(
  `// Generated by scripts/generate-mcpb-tools.mjs; do not edit by hand.
export const FALLBACK_TOOLS = ${JSON.stringify(fallbackTools, null, 2)};
`,
  { ...prettierOptions, parser: 'babel' }
);

if (checkMode) {
  const [actualManifest, actualFallbackTools] = await Promise.all([
    readFile(manifestPath, 'utf8'),
    readFile(fallbackToolsPath, 'utf8'),
  ]);

  const staleFiles = [];
  if (actualManifest !== nextManifest) {
    staleFiles.push('mcpb/remnote-local/manifest.json');
  }
  if (actualFallbackTools !== nextFallbackTools) {
    staleFiles.push('mcpb/remnote-local/server/fallback-tools.generated.js');
  }

  if (staleFiles.length > 0) {
    throw new Error(
      `Generated MCPB tool metadata is stale: ${staleFiles.join(', ')}. Run npm run generate:mcpb-tools.`
    );
  }

  log('Generated MCPB tool metadata is current.');
} else {
  await Promise.all([
    writeFile(manifestPath, nextManifest, 'utf8'),
    writeFile(fallbackToolsPath, nextFallbackTools, 'utf8'),
  ]);
  log('Generated MCPB tool metadata.');
}
