import { createDefaultLibrary, createResolver, createCodeGenerator, loadManifest } from "@specverse/engines/realize";
import { UnifiedSpecVerseParser } from "@specverse/engine-parser";
import { readFileSync } from "fs";
import { resolve } from "path";
async function testV33Generation() {
  console.log("\u{1F9EA} Testing v3.3 Implementation Types System\n");
  try {
    console.log("\u{1F4DA} Step 1: Loading Implementation Type Library...");
    const library = await createDefaultLibrary(process.cwd());
    const allTypes = library.find({});
    console.log(`   \u2705 Library loaded with ${allTypes.length} implementation types`);
    allTypes.forEach((type) => {
      console.log(`   - ${type.name} v${type.version} (${type.type})`);
    });
    console.log();
    console.log("\u{1F4C4} Step 2: Loading v3.3 Manifest...");
    const manifestPath = resolve(process.cwd(), "examples/v33-test/fastify-prisma-manifest.yaml");
    const manifest = loadManifest(manifestPath);
    console.log(`   \u2705 Manifest loaded: ${manifest.name}`);
    console.log(`   - Version: ${manifest.version}`);
    console.log(`   - Implementation Types: ${manifest.implementationTypes?.length || 0}`);
    console.log(`   - Capability Mappings: ${Object.keys(manifest.capabilityMappings || {}).length}`);
    console.log();
    console.log("\u{1F50D} Step 3: Creating Capability Resolver...");
    const resolver = createResolver(library, manifest);
    console.log(`   \u2705 Resolver created`);
    console.log();
    console.log("\u{1F4DD} Step 4: Parsing Test Spec...");
    const specPath = resolve(process.cwd(), "examples/01-fundamentals/01-01-basic-model.specly");
    const specContent = readFileSync(specPath, "utf8");
    const schemaPath = resolve(process.cwd(), "schema/SPECVERSE-SCHEMA.json");
    const schema = JSON.parse(readFileSync(schemaPath, "utf8"));
    const parser = new UnifiedSpecVerseParser(schema);
    const parseResult = parser.parse(specContent, "specly");
    if (parseResult.errors && parseResult.errors.length > 0) {
      console.error("   \u274C Parse errors:");
      parseResult.errors.forEach((err) => {
        console.error(`      - ${err.message}`);
      });
      return;
    }
    console.log(`   \u2705 Spec parsed successfully`);
    console.log(`   - Component: ${parseResult.ast?.components ? Object.keys(parseResult.ast.components)[0] : "unknown"}`);
    console.log(`   - Models: ${parseResult.ast?.components?.[Object.keys(parseResult.ast.components)[0]]?.models?.length || 0}`);
    console.log(`   - Controllers: ${parseResult.ast?.components?.[Object.keys(parseResult.ast.components)[0]]?.controllers?.length || 0}`);
    const deployment = {
      environment: "development",
      instances: {
        "apiServer": {
          name: "Test API Server",
          type: "api-server",
          advertises: ["api.rest", "api.rest.crud"],
          uses: ["storage.database"]
        },
        "database": {
          name: "Test Database",
          type: "storage",
          advertises: ["storage.database", "storage.prisma"],
          uses: []
        }
      }
    };
    console.log(`   - Mocked deployment for testing`);
    console.log(`   - Instances: ${Object.keys(deployment.instances || {}).length}`);
    console.log();
    console.log("\u{1F517} Step 5: Testing Capability Resolution...");
    const apiInstance = deployment.instances?.["apiServer"];
    if (!apiInstance) {
      console.error("   \u274C No api-server instance found");
      return;
    }
    console.log(`   Testing instance: ${apiInstance.name}`);
    console.log(`   Advertises: ${apiInstance.advertises?.join(", ")}`);
    const resolved = resolver.resolveForInstance(apiInstance);
    console.log(`   \u2705 Resolved ${resolved.length} implementation type(s)`);
    resolved.forEach((impl2) => {
      console.log(`   - ${impl2.implementationType.name}`);
      console.log(`     Capability: ${impl2.capability}`);
      console.log(`     Templates: ${Object.keys(impl2.implementationType.codeTemplates).join(", ")}`);
    });
    console.log();
    console.log("\u2699\uFE0F  Step 6: Testing Code Generation...");
    const codeGen = createCodeGenerator({ outputDir: "/tmp/v33-test" });
    const componentName = Object.keys(parseResult.ast?.components || {})[0];
    const component = parseResult.ast?.components?.[componentName];
    const model = component?.models?.[0];
    const controller = component?.controllers?.[0] || {
      name: `${model?.name}Controller`,
      path: `/api/${model?.name?.toLowerCase()}`,
      model: model?.name,
      endpoints: [
        { operation: "create", method: "POST", path: "/" },
        { operation: "retrieve", method: "GET", path: "/:id" },
        { operation: "update", method: "PUT", path: "/:id" },
        { operation: "delete", method: "DELETE", path: "/:id" },
        { operation: "list", method: "GET", path: "/" }
      ]
    };
    if (!model) {
      console.error("   \u274C No model found in spec");
      return;
    }
    console.log(`   Generating code for model: ${model.name}`);
    const impl = resolved[0];
    const templates = ["routes", "services", "schema"];
    for (const templateName of templates) {
      try {
        console.log(`   Testing ${templateName} template...`);
        const output = await codeGen.generateFromTemplate(
          impl,
          templateName,
          {
            spec: parseResult.ast,
            model,
            controller,
            models: [model]
          },
          { outputDir: "/tmp/v33-test" }
        );
        console.log(`   \u2705 ${templateName}: ${output.filePath}`);
        console.log(`      Code length: ${output.code.length} characters`);
        console.log(`      First 100 chars: ${output.code.substring(0, 100)}...`);
      } catch (error) {
        console.error(`   \u274C ${templateName} failed: ${error instanceof Error ? error.message : String(error)}`);
      }
    }
    console.log();
    console.log("\u2705 All tests completed!");
    console.log("\n\u{1F4CA} Summary:");
    console.log(`   - Library: \u2705 Loaded`);
    console.log(`   - Manifest: \u2705 Loaded`);
    console.log(`   - Spec: \u2705 Parsed`);
    console.log(`   - Resolution: \u2705 Working`);
    console.log(`   - Generation: \u2705 Working`);
    console.log("\n\u{1F389} v3.3 Implementation Types System is operational!");
  } catch (error) {
    console.error("\n\u274C Test failed:", error instanceof Error ? error.message : String(error));
    if (error instanceof Error && error.stack) {
      console.error("\nStack trace:");
      console.error(error.stack);
    }
    process.exit(1);
  }
}
testV33Generation();
