// mcp_server_dart/tool/build_skill_assets.dart
//
// Reads `<repo_root>/plugin/` and emits
// `mcp_server_dart/lib/src/skill_assets.g.dart`. Run via
// `dart run mcp_server_dart/tool/build_skill_assets.dart` or
// `make sync-skills` from the repo root.

import 'dart:convert';
import 'dart:io';

const expectedSkillIds = [
  'flutter-mcp-toolkit-guide',
  'flutter-mcp-toolkit-setup',
  'flutter-mcp-toolkit-inspect',
  'flutter-mcp-toolkit-control',
  'flutter-mcp-toolkit-debug',
  'flutter-mcp-toolkit-custom-tools',
  'flutter-mcp',
  'flutter-mcp-cli-runtime-validation',
  'flutter-mcp-toolkit-repo-maintainer',
];

void main() {
  final repoRoot = _findRepoRoot();
  final pluginDir = Directory('${repoRoot.path}/plugin');
  if (!pluginDir.existsSync()) {
    stderr.writeln('plugin/ not found at ${pluginDir.path}');
    exit(1);
  }

  final cursorManifest = File(
    '${pluginDir.path}/.cursor-plugin/plugin.json',
  ).readAsStringSync();
  final codexManifest = File(
    '${pluginDir.path}/.codex-plugin/plugin.json',
  ).readAsStringSync();
  final mcpConfig = File('${pluginDir.path}/mcp.json').readAsStringSync();

  final skills = <_Skill>[];
  for (final id in expectedSkillIds) {
    final file = File('${pluginDir.path}/skills/$id/SKILL.md');
    if (!file.existsSync()) {
      stderr.writeln('Missing skill: ${file.path}');
      exit(1);
    }
    final content = file.readAsStringSync();
    final parts = _splitFrontmatter(content);
    skills.add(
      _Skill(
        id: id,
        frontmatter: parts.frontmatter,
        body: parts.body,
        relativePath: 'skills/$id/SKILL.md',
      ),
    );
  }

  final out = File(
    '${repoRoot.path}/mcp_server_dart/lib/src/skill_assets.g.dart',
  );
  out.writeAsStringSync(
    _render(
      skills: skills,
      cursorManifest: cursorManifest,
      codexManifest: codexManifest,
      mcpConfig: mcpConfig,
    ),
  );
  stdout.writeln('Wrote ${out.path}');
}

class _Skill {
  _Skill({
    required this.id,
    required this.frontmatter,
    required this.body,
    required this.relativePath,
  });
  final String id;
  final String frontmatter;
  final String body;
  final String relativePath;
}

class _Parts {
  _Parts(this.frontmatter, this.body);
  final String frontmatter;
  final String body;
}

_Parts _splitFrontmatter(final String content) {
  if (!content.startsWith('---\n')) {
    throw const FormatException('SKILL.md must start with frontmatter');
  }
  final end = content.indexOf('\n---\n', 4);
  if (end < 0) throw const FormatException('Unterminated frontmatter');
  return _Parts(content.substring(4, end), content.substring(end + 5));
}

Directory _findRepoRoot() {
  var dir = Directory.current;
  while (dir.parent.path != dir.path) {
    if (Directory('${dir.path}/.git').existsSync()) return dir;
    dir = dir.parent;
  }
  throw StateError('Not in a git repo');
}

String _render({
  required final List<_Skill> skills,
  required final String cursorManifest,
  required final String codexManifest,
  required final String mcpConfig,
}) {
  final buf = StringBuffer();
  buf.writeln('// AUTOGENERATED by tool/build_skill_assets.dart. Do not edit.');
  buf.writeln('// Run `make sync-skills` from the repo root to regenerate.');
  buf.writeln(
    '// ignore_for_file: leading_newlines_in_multiline_strings, unnecessary_raw_strings',
  );
  buf.writeln();
  buf.writeln('class SkillAsset {');
  buf.writeln('  const SkillAsset({');
  buf.writeln('    required this.id,');
  buf.writeln('    required this.frontmatter,');
  buf.writeln('    required this.body,');
  buf.writeln('    required this.relativePath,');
  buf.writeln('  });');
  buf.writeln('  final String id;');
  buf.writeln('  final String frontmatter;');
  buf.writeln('  final String body;');
  buf.writeln('  final String relativePath;');
  buf.writeln('}');
  buf.writeln();
  buf.writeln('class SkillAssets {');
  buf.writeln('  static const List<SkillAsset> skills = [');
  for (final s in skills) {
    buf.writeln('    SkillAsset(');
    buf.writeln("      id: '${s.id}',");
    buf.writeln('      frontmatter: ${_dartString(s.frontmatter)},');
    buf.writeln('      body: ${_dartString(s.body)},');
    buf.writeln("      relativePath: '${s.relativePath}',");
    buf.writeln('    ),');
  }
  buf.writeln('  ];');
  buf.writeln();
  buf.writeln(
    '  static const String cursorPluginManifest = ${_dartString(cursorManifest)};',
  );
  buf.writeln(
    '  static const String codexPluginManifest = ${_dartString(codexManifest)};',
  );
  buf.writeln(
    '  static const String mcpServerConfig = ${_dartString(mcpConfig)};',
  );
  buf.writeln('}');
  return buf.toString();
}

String _dartString(final String s) {
  // Use raw triple-quoted strings; escape any `'''` sequences inside.
  if (s.contains("'''")) {
    return jsonEncode(s);
  }
  return "r'''$s'''";
}
