import * as vscode from "vscode";
import { join, dirname, basename, extname } from "path";
import { exec } from "child_process";
import { promisify } from "util";
const execAsync = promisify(exec);
function activate(context) {
  console.log("SpecVerse v3.5 extension activated");
  const provider = new SpecVerseProvider(context);
  const diagnostics = vscode.languages.createDiagnosticCollection("specverse");
  context.subscriptions.push(diagnostics);
  const onSaveListener = vscode.workspace.onDidSaveTextDocument(async (document) => {
    if (isSpecVerseDocument(document)) {
      const config = vscode.workspace.getConfiguration("specverse");
      if (config.get("validation.onSave")) {
        await validateDocument(document, diagnostics);
      }
      if (config.get("diagrams.autoGenerate")) {
        await generateDiagramForDocument(document);
      }
    }
  });
  context.subscriptions.push(onSaveListener);
  let validationTimeout;
  const onChangeListener = vscode.workspace.onDidChangeTextDocument((event) => {
    const document = event.document;
    if (isSpecVerseDocument(document)) {
      clearTimeout(validationTimeout);
      validationTimeout = setTimeout(async () => {
        const config = vscode.workspace.getConfiguration("specverse");
        if (config.get("validation.enabled")) {
          await validateDocument(document, diagnostics);
        }
      }, 1e3);
    }
  });
  context.subscriptions.push(onChangeListener);
  const packageJson = require("../package.json");
  const autoGeneratedCommands = packageJson.contributes.commands.filter((cmd) => cmd.command.startsWith("specverse.")).map((cmd) => {
    const commandName = cmd.command.replace("specverse.", "");
    return vscode.commands.registerCommand(cmd.command, async (uri) => {
      const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
      if (document && isSpecVerseDocument(document)) {
        await executeCliCommand(document, commandName);
      }
    });
  });
  const commands = [
    vscode.commands.registerCommand("specverse.validate", async (uri) => {
      const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
      if (document && isSpecVerseDocument(document)) {
        await validateDocument(document, diagnostics);
        vscode.window.showInformationMessage("SpecVerse validation completed");
      }
    }),
    vscode.commands.registerCommand("specverse.format", async () => {
      const editor = vscode.window.activeTextEditor;
      if (editor && isSpecVerseDocument(editor.document)) {
        await formatDocument(editor);
      }
    }),
    vscode.commands.registerCommand("specverse.generateDiagram", async (uri) => {
      const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
      if (document && isSpecVerseDocument(document)) {
        await generateDiagramForDocument(document);
      }
    }),
    vscode.commands.registerCommand("specverse.generateDocs", async (uri) => {
      const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
      if (document && isSpecVerseDocument(document)) {
        await generateDocsForDocument(document);
      }
    }),
    vscode.commands.registerCommand("specverse.generateAI", async (uri) => {
      const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
      if (document && isSpecVerseDocument(document)) {
        await generateAIForDocument(document);
      }
    }),
    vscode.commands.registerCommand("specverse.processSpecly", async (uri) => {
      const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
      if (document && document.fileName.endsWith(".specly")) {
        await processSpeclyDocument(document);
      } else {
        vscode.window.showErrorMessage("This command only works with .specly files");
      }
    }),
    vscode.commands.registerCommand("specverse.infer", async (uri) => {
      const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
      if (document && isSpecVerseDocument(document)) {
        await inferCompleteSystemForDocument(document);
      }
    }),
    vscode.commands.registerCommand("specverse.testCycle", async (uri) => {
      const document = uri ? await vscode.workspace.openTextDocument(uri) : vscode.window.activeTextEditor?.document;
      if (document && isSpecVerseDocument(document)) {
        await runTestCycleForDocument(document);
      }
    }),
    vscode.commands.registerCommand("specverse.batchGenerate", async () => {
      await runBatchDiagramGeneration();
    }),
    vscode.commands.registerCommand("specverse.migrate", async (uri) => {
      let targetDir;
      if (uri) {
        const stat = await vscode.workspace.fs.stat(uri);
        if (stat.type === vscode.FileType.Directory) {
          targetDir = uri.fsPath;
        } else {
          targetDir = dirname(uri.fsPath);
        }
      } else if (vscode.window.activeTextEditor) {
        targetDir = dirname(vscode.window.activeTextEditor.document.fileName);
      } else if (vscode.workspace.workspaceFolders?.[0]) {
        targetDir = vscode.workspace.workspaceFolders[0].uri.fsPath;
      } else {
        vscode.window.showErrorMessage("No directory to migrate. Open a file or folder first.");
        return;
      }
      await runMigrateCommand(targetDir);
    })
  ];
  context.subscriptions.push(...commands, ...autoGeneratedCommands);
  const completionProvider = vscode.languages.registerCompletionItemProvider(
    { scheme: "file", language: "specly" },
    new SpecVerseCompletionProvider(),
    ":",
    " "
  );
  context.subscriptions.push(completionProvider);
  const hoverProvider = vscode.languages.registerHoverProvider(
    { scheme: "file", language: "specly" },
    new SpecVerseHoverProvider()
  );
  context.subscriptions.push(hoverProvider);
  const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
  statusBar.command = "specverse.validate";
  context.subscriptions.push(statusBar);
  const onActiveEditorChange = vscode.window.onDidChangeActiveTextEditor((editor) => {
    if (editor && isSpecVerseDocument(editor.document)) {
      statusBar.text = "$(check) SpecVerse";
      statusBar.tooltip = "Click to validate SpecVerse file";
      statusBar.show();
    } else {
      statusBar.hide();
    }
  });
  context.subscriptions.push(onActiveEditorChange);
  if (vscode.window.activeTextEditor && isSpecVerseDocument(vscode.window.activeTextEditor.document)) {
    statusBar.text = "$(check) SpecVerse";
    statusBar.tooltip = "Click to validate SpecVerse file";
    statusBar.show();
  }
}
class SpecVerseProvider {
  constructor(context) {
    this.context = context;
  }
  getCliPath() {
    const config = vscode.workspace.getConfiguration("specverse");
    return config.get("cli.path") || "specverse";
  }
}
class SpecVerseCompletionProvider {
  provideCompletionItems(document, position, token, context) {
    if (!isSpecVerseDocument(document)) {
      return [];
    }
    const line = document.lineAt(position).text;
    const linePrefix = line.substring(0, position.character);
    const context_info = analyzeContext(document, position);
    const completions = [];
    if (context_info.isAttributeType) {
      const types = [
        "String",
        "Text",
        "Integer",
        "Number",
        "Boolean",
        "Date",
        "DateTime",
        "UUID",
        "Email",
        "URL",
        "JSON",
        "Object",
        "Array"
      ];
      types.forEach((type) => {
        const item = new vscode.CompletionItem(type, vscode.CompletionItemKind.TypeParameter);
        item.documentation = new vscode.MarkdownString(`SpecVerse type: \`${type}\``);
        completions.push(item);
      });
    }
    if (context_info.isModifier) {
      const modifiers = [
        { name: "required", description: "Field is required" },
        { name: "unique", description: "Field must be unique" },
        { name: "searchable", description: "Field is searchable" },
        { name: "verified", description: "Field requires verification" },
        { name: "auto=uuid4", description: "Auto-generate UUID" },
        { name: "auto=now", description: "Auto-set current timestamp" },
        { name: "auto=token", description: "Auto-generate token" },
        { name: "default=", description: "Default value" },
        { name: "min=", description: "Minimum value" },
        { name: "max=", description: "Maximum value" }
      ];
      modifiers.forEach((mod) => {
        const item = new vscode.CompletionItem(mod.name, vscode.CompletionItemKind.Keyword);
        item.documentation = new vscode.MarkdownString(mod.description);
        if (mod.name.endsWith("=")) {
          item.insertText = mod.name;
          item.command = { command: "editor.action.triggerSuggest", title: "Trigger Suggest" };
        }
        completions.push(item);
      });
    }
    if (context_info.isRelationshipType) {
      const relationships = [
        { name: "hasMany", description: "One-to-many relationship" },
        { name: "hasOne", description: "One-to-one relationship" },
        { name: "belongsTo", description: "Many-to-one relationship" },
        { name: "manyToMany", description: "Many-to-many relationship" }
      ];
      relationships.forEach((rel) => {
        const item = new vscode.CompletionItem(rel.name, vscode.CompletionItemKind.Keyword);
        item.documentation = new vscode.MarkdownString(rel.description);
        completions.push(item);
      });
    }
    if (context_info.isTopLevel) {
      const sections = [
        // v3.5 container format
        "components",
        "deployments",
        // Component-level sections
        "component",
        "deployment",
        "version",
        "description",
        "tags",
        "import",
        "export",
        "models",
        "controllers",
        "services",
        "views",
        "events",
        // v3.5 CURED operations
        "cured",
        // Deployment sections
        "instances",
        "environment",
        "communications",
        // v3.5 advanced features
        "profiles",
        "profile-attachment",
        "steps",
        "subscribes_to"
      ];
      sections.forEach((section) => {
        const item = new vscode.CompletionItem(section, vscode.CompletionItemKind.Module);
        if (section === "components") {
          item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 container format: array of components`);
        } else if (section === "deployments") {
          item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 container format: array of deployments`);
        } else if (section === "cured") {
          item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 CURED operations: Create, Update, Retrieve, Evolve, Destroy`);
        } else if (section === "instances") {
          item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 deployment instances: controllers, services, views, communications`);
        } else if (section === "communications") {
          item.documentation = new vscode.MarkdownString(`SpecVerse v3.5 communication channels: pubsub, rpc, queue, streaming`);
        } else {
          item.documentation = new vscode.MarkdownString(`SpecVerse section: \`${section}\``);
        }
        completions.push(item);
      });
    }
    if (context_info.isDeploymentProperty) {
      const deploymentProps = [
        { name: "component", description: "Component reference for this instance" },
        { name: "namespace", description: "Logical namespace for this instance" },
        { name: "advertises", description: "Capabilities this instance advertises" },
        { name: "uses", description: "Capabilities this instance uses" },
        { name: "scale", description: "Number of instances to run" },
        { name: "capabilities", description: "Available capabilities on communication channel" },
        { name: "type", description: "Communication channel type (pubsub, rpc, queue, streaming)" }
      ];
      deploymentProps.forEach((prop) => {
        const item = new vscode.CompletionItem(prop.name, vscode.CompletionItemKind.Property);
        item.documentation = new vscode.MarkdownString(prop.description);
        completions.push(item);
      });
    }
    return completions;
  }
}
class SpecVerseHoverProvider {
  provideHover(document, position, token) {
    if (!isSpecVerseDocument(document)) {
      return;
    }
    const line = document.lineAt(position).text;
    const wordRange = document.getWordRangeAtPosition(position);
    const word = wordRange ? document.getText(wordRange) : "";
    const attributeMatch = line.match(/^\s*(\w+):\s*(\w+)(.*)/);
    if (attributeMatch && wordRange) {
      const [, name, type, modifiers] = attributeMatch;
      if (word === type) {
        return new vscode.Hover([
          `**SpecVerse Type:** \`${type}\``,
          "",
          getTypeDocumentation(type)
        ]);
      }
      if (word === name) {
        return new vscode.Hover([
          `**Attribute:** \`${name}\``,
          `**Type:** \`${type}\``,
          `**Modifiers:** \`${modifiers.trim() || "none"}\``,
          "",
          "SpecVerse attribute definition using conventions"
        ]);
      }
    }
    const flowMatch = line.match(/flow:\s*(.+)/);
    if (flowMatch && line.includes(word)) {
      return new vscode.Hover([
        "**SpecVerse Lifecycle Flow**",
        "",
        "Shorthand lifecycle definition.",
        "States are connected with `->` transitions.",
        "",
        "Example: `draft -> published -> archived`"
      ]);
    }
    if (word === "steps") {
      return new vscode.Hover([
        "**Steps** *(Array<string>)*",
        "",
        "Sequential steps describing the execution process.",
        "",
        "**Usage:** Available in behaviors, controller actions, service operations, and CURED operations.",
        "",
        "**Example:**",
        "```yaml",
        "steps:",
        '  - "Validate input data"',
        '  - "Process business logic"',
        '  - "Return results"',
        "```"
      ]);
    }
    if (word === "parameters") {
      return new vscode.Hover([
        "**Parameters** *(Object)*",
        "",
        "Input parameters for executable properties (actions, operations, behaviors).",
        "",
        "**Usage:** Replaces `payload:` in v3.5 - defines input data structure.",
        "",
        "**Example:**",
        "```yaml",
        "parameters:",
        "  userId: UUID required",
        "  name: String required max=100",
        "```"
      ]);
    }
    if (word === "publishes") {
      return new vscode.Hover([
        "**Publishes** *(Array<string>)*",
        "",
        "Events published by this executable property.",
        "",
        "**Usage:** Replaces `events:` in v3.5 - defines output events.",
        "",
        "**Example:**",
        "```yaml",
        "publishes: [UserCreated, EmailSent]",
        "```"
      ]);
    }
    if (word === "subscribes_to") {
      return new vscode.Hover([
        "**Subscribes To** *(Array<string> | Object)*",
        "",
        "Events this component subscribes to.",
        "",
        "**Formats:**",
        '- Array: `["EventName1", "EventName2"]`',
        '- Object: `EventName: "handlerMethod"`',
        "",
        "**Example:**",
        "```yaml",
        "subscribes_to:",
        "  - UserCreated",
        "  - OrderPlaced",
        "```"
      ]);
    }
    if (word === "profiles") {
      return new vscode.Hover([
        "**Profiles** *(Array<string>)*",
        "",
        "Runtime profiles that can be applied to models.",
        "",
        "**Usage:** Defines which profiles are available for profile attachment.",
        "",
        "**Example:**",
        "```yaml",
        'profiles: ["CustomerProfile", "AdminProfile"]',
        "```"
      ]);
    }
    if (word === "profile-attachment") {
      return new vscode.Hover([
        "**Profile Attachment** *(Object)*",
        "",
        "Configuration for attaching profiles to models at runtime.",
        "",
        "**Properties:**",
        "- `profiles`: Array of available profiles",
        "- `conditions`: Optional conditions for attachment",
        "- `priority`: Attachment priority (1-10)",
        "",
        "**Example:**",
        "```yaml",
        "profile-attachment:",
        '  profiles: ["VisibilityProfile"]',
        '  conditions: ["user.role === admin"]',
        "  priority: 5",
        "```"
      ]);
    }
    if (word === "instances") {
      return new vscode.Hover([
        "**Instances** *(Object)*",
        "",
        "Logical deployment instances for controllers, services, views, and communications.",
        "",
        "**Structure:**",
        "- `controllers`: Controller instance configurations",
        "- `services`: Service instance configurations",
        "- `views`: View instance configurations",
        "- `communications`: Communication channel definitions"
      ]);
    }
    if (word === "advertises") {
      return new vscode.Hover([
        "**Advertises** *(string | Array<string>)*",
        "",
        "Capabilities that this instance makes available to other instances.",
        "",
        "**Common patterns:**",
        '- `"*"` - All capabilities',
        '- `"behaviors.*"` - All behavior capabilities',
        '- `["create", "read", "update"]` - Specific operations'
      ]);
    }
    if (word === "uses") {
      return new vscode.Hover([
        "**Uses** *(Array<string>)*",
        "",
        "Capabilities that this instance consumes from communication channels.",
        "",
        "**Examples:**",
        '- `["user.*", "order.create"]` - Specific capability patterns',
        '- `["database.*"]` - All database capabilities'
      ]);
    }
    if (word === "capabilities") {
      return new vscode.Hover([
        "**Capabilities** *(Array<string>)*",
        "",
        "List of capabilities available on this communication channel.",
        "",
        "**Used by:** Communication channel definitions to specify what operations are available for instances to advertise/use."
      ]);
    }
    return;
  }
}
function isSpecVerseDocument(document) {
  return document.languageId === "specly" || document.fileName.endsWith(".specly");
}
function analyzeContext(document, position) {
  const line = document.lineAt(position).text;
  const linePrefix = line.substring(0, position.character);
  const isInAttributesSection = (() => {
    for (let i = position.line; i >= 0; i--) {
      const checkLine = document.lineAt(i).text;
      if (checkLine.trim() === "attributes:") return true;
      if (checkLine.trim().endsWith(":") && !checkLine.includes("  ")) return false;
    }
    return false;
  })();
  const isInRelationshipsSection = (() => {
    for (let i = position.line; i >= 0; i--) {
      const checkLine = document.lineAt(i).text;
      if (checkLine.trim() === "relationships:") return true;
      if (checkLine.trim().endsWith(":") && !checkLine.includes("  ")) return false;
    }
    return false;
  })();
  const isInDeploymentSection = (() => {
    for (let i = position.line; i >= 0; i--) {
      const checkLine = document.lineAt(i).text;
      if (checkLine.trim() === "instances:" || checkLine.trim() === "communications:") return true;
      if (checkLine.trim().endsWith(":") && !checkLine.includes("    ")) return false;
    }
    return false;
  })();
  return {
    isAttributeType: isInAttributesSection && linePrefix.match(/^\s*\w+:\s*$/),
    isModifier: isInAttributesSection && linePrefix.match(/^\s*\w+:\s*\w+\s+$/),
    isRelationshipType: isInRelationshipsSection && linePrefix.match(/^\s*\w+:\s*$/),
    isTopLevel: !linePrefix.includes("  ") && linePrefix.trim().endsWith(":"),
    isDeploymentProperty: isInDeploymentSection && linePrefix.match(/^\s+\w+:\s*$/)
  };
}
function getTypeDocumentation(type) {
  const docs = {
    "String": "Variable-length text field (default max 255 characters)",
    "Text": "Long text field for large content",
    "Integer": "Whole number",
    "Number": "Decimal number",
    "Boolean": "True/false value",
    "Date": "Date without time",
    "DateTime": "Date and time timestamp",
    "UUID": "Universally Unique Identifier",
    "Email": "Email address with validation",
    "URL": "Web URL with validation",
    "JSON": "JSON object or array",
    "Object": "Structured object",
    "Array": "List of values"
  };
  return docs[type] || "SpecVerse data type";
}
async function validateDocument(document, diagnostics) {
  try {
    diagnostics.clear();
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    const workingDir = dirname(document.fileName);
    const { stdout: stdout2, stderr } = await execAsync(`"${cliPath}" validate "${document.fileName}"`, { cwd: workingDir });
    if (stdout2.includes("\u2705") && !stderr) {
      return;
    }
    const errors = [];
    const allOutput = (stdout2 + "\n" + stderr).split("\n");
    allOutput.forEach((line) => {
      line = line.trim();
      if (!line) return;
      let errorMessage = "";
      let severity = vscode.DiagnosticSeverity.Error;
      let lineNumber = 0;
      const numberedErrorMatch = line.match(/^\d+\.\s*(.+)$/);
      if (numberedErrorMatch) {
        errorMessage = numberedErrorMatch[1].trim();
      } else if (line.includes("\u274C") && !line.includes("Validation failed")) {
        errorMessage = line.replace(/❌/g, "").trim();
      } else if (line.includes("Error:")) {
        errorMessage = line.replace(/Error:/, "").trim();
      } else if (line.includes("\u26A0\uFE0F") || line.includes("Warning:")) {
        errorMessage = line.replace(/⚠️|Warning:/, "").trim();
        severity = vscode.DiagnosticSeverity.Warning;
      } else if (line.includes("at line") || line.includes("line:")) {
        const lineMatch = line.match(/(?:at line|line:?\s*)(\d+)/i);
        if (lineMatch) {
          lineNumber = Math.max(0, parseInt(lineMatch[1]) - 1);
        }
        errorMessage = line;
      } else if (line.includes("should") && (line.includes("property") || line.includes("type") || line.includes("required"))) {
        errorMessage = line;
        severity = vscode.DiagnosticSeverity.Error;
      } else if (line.includes("Parse error") || line.includes("Syntax error")) {
        errorMessage = line;
      } else if (line.includes("Validation failed") || line.includes("Validation Errors:") || line.includes("\u{1F4DD}")) {
        return;
      }
      if (errorMessage) {
        const diagnostic = new vscode.Diagnostic(
          new vscode.Range(lineNumber, 0, lineNumber, Number.MAX_SAFE_INTEGER),
          errorMessage,
          severity
        );
        diagnostic.source = "SpecVerse";
        errors.push(diagnostic);
      }
    });
    if (errors.length > 0) {
      diagnostics.set(document.uri, errors);
    } else if (!stdout2.includes("\u2705")) {
      const diagnostic = new vscode.Diagnostic(
        new vscode.Range(0, 0, 0, 0),
        "SpecVerse validation completed with unknown status. Check output for details.",
        vscode.DiagnosticSeverity.Information
      );
      diagnostic.source = "SpecVerse";
      diagnostics.set(document.uri, [diagnostic]);
    }
  } catch (error) {
    if (error.code === "ENOENT") {
      const diagnostic2 = new vscode.Diagnostic(
        new vscode.Range(0, 0, 0, 0),
        "SpecVerse CLI not found. Please configure cli.path in settings or ensure specverse is on PATH",
        vscode.DiagnosticSeverity.Error
      );
      diagnostic2.source = "SpecVerse";
      diagnostics.set(document.uri, [diagnostic2]);
      return;
    }
    if (error.stdout) {
      const errors = [];
      const errorLines = error.stdout.split("\n");
      errorLines.forEach((line) => {
        line = line.trim();
        if (!line) return;
        let errorMessage = "";
        let severity = vscode.DiagnosticSeverity.Error;
        let lineNumber = 0;
        const numberedErrorMatch = line.match(/^\d+\.\s*(.+)$/);
        if (numberedErrorMatch) {
          errorMessage = numberedErrorMatch[1].trim();
        } else if (line.includes("\u274C") && !line.includes("Validation failed")) {
          errorMessage = line.replace(/❌/g, "").trim();
        } else if (line.includes("Unknown property") || line.includes("should") || line.includes("required")) {
          errorMessage = line;
        } else if (line.includes("/") && line.includes(":")) {
          errorMessage = line;
        } else if (line.includes("\u26A0\uFE0F") || line.includes("Warning:")) {
          errorMessage = line.replace(/⚠️|Warning:/, "").trim();
          severity = vscode.DiagnosticSeverity.Warning;
        } else if (line.includes("Validation failed") || line.includes("Validation Errors:") || line.includes("\u{1F4DD}")) {
          return;
        }
        if (errorMessage) {
          const diagnostic2 = new vscode.Diagnostic(
            new vscode.Range(lineNumber, 0, lineNumber, Number.MAX_SAFE_INTEGER),
            errorMessage,
            severity
          );
          diagnostic2.source = "SpecVerse";
          errors.push(diagnostic2);
        }
      });
      if (errors.length > 0) {
        diagnostics.set(document.uri, errors);
        return;
      }
    }
    const diagnostic = new vscode.Diagnostic(
      new vscode.Range(0, 0, 0, 0),
      `SpecVerse CLI error: ${error.message}`,
      vscode.DiagnosticSeverity.Error
    );
    diagnostic.source = "SpecVerse";
    diagnostics.set(document.uri, [diagnostic]);
  }
}
async function formatDocument(editor) {
  try {
    const document = editor.document;
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    vscode.window.showInformationMessage("Format command is not currently available in SpecVerse CLI");
    return;
    if (stdout) {
      const edit = new vscode.WorkspaceEdit();
      const fullRange = new vscode.Range(
        document.positionAt(0),
        document.positionAt(document.getText().length)
      );
      edit.replace(document.uri, fullRange, stdout);
      await vscode.workspace.applyEdit(edit);
    }
  } catch (error) {
    vscode.window.showErrorMessage(`Format failed: ${error.message}`);
  }
}
async function generateDiagramForDocument(document) {
  try {
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    const diagramType = await vscode.window.showQuickPick([
      "er",
      "sequence",
      "architecture",
      "lifecycle",
      "deployment",
      "all"
    ], {
      placeHolder: "Select diagram type to generate"
    });
    if (!diagramType) return;
    const workingDir = dirname(document.fileName);
    const baseName = basename(document.fileName, extname(document.fileName));
    const outputFile = join(workingDir, `${baseName}-${diagramType}.mmd`);
    console.log(`[SpecVerse] Working directory: ${workingDir}`);
    console.log(`[SpecVerse] Output file: ${outputFile}`);
    console.log(`[SpecVerse] Command: "${cliPath}" gen uml "${document.fileName}" --output "${outputFile}"`);
    await execAsync(`"${cliPath}" gen uml "${document.fileName}" --output "${outputFile}"`, { cwd: workingDir });
    vscode.window.showInformationMessage(`${diagramType} diagram generated successfully`);
  } catch (error) {
    vscode.window.showErrorMessage(`Diagram generation failed: ${error.message}`);
  }
}
async function generateDocsForDocument(document) {
  try {
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    const format = await vscode.window.showQuickPick([
      "markdown",
      "html",
      "openapi"
    ], {
      placeHolder: "Select documentation format"
    });
    if (!format) return;
    const workingDir = dirname(document.fileName);
    await execAsync(`"${cliPath}" gen docs "${document.fileName}"`, { cwd: workingDir });
    vscode.window.showInformationMessage(`${format} documentation generated successfully`);
  } catch (error) {
    vscode.window.showErrorMessage(`Documentation generation failed: ${error.message}`);
  }
}
async function generateAIForDocument(document) {
  try {
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    const workingDir = dirname(document.fileName);
    await execAsync(`"${cliPath}" gen views "${document.fileName}"`, { cwd: workingDir });
    vscode.window.showInformationMessage("AI-optimized specification generated successfully");
  } catch (error) {
    vscode.window.showErrorMessage(`AI generation failed: ${error.message}`);
  }
}
async function processSpeclyDocument(document) {
  try {
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    const workingDir = dirname(document.fileName);
    const outputFile = document.fileName.replace(".specly", ".yaml");
    await execAsync(`"${cliPath}" gen yaml "${document.fileName}" --output "${outputFile}"`, { cwd: workingDir });
    vscode.window.showInformationMessage(`Generated expanded YAML: ${outputFile}`);
    const openFile = await vscode.window.showInformationMessage(
      "Open generated .yaml file?",
      "Open",
      "Cancel"
    );
    if (openFile === "Open") {
      const yamlDocument = await vscode.workspace.openTextDocument(outputFile);
      await vscode.window.showTextDocument(yamlDocument);
    }
  } catch (error) {
    vscode.window.showErrorMessage(`Processing failed: ${error.message}`);
  }
}
async function inferCompleteSystemForDocument(document) {
  try {
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    if (!config.get("inference.enabled")) {
      vscode.window.showInformationMessage("AI inference is disabled in settings");
      return;
    }
    const outputFile = document.fileName.replace(".specly", "-inferred.specly");
    await vscode.window.withProgress({
      location: vscode.ProgressLocation.Notification,
      title: "Running AI inference...",
      cancellable: false
    }, async (progress) => {
      progress.report({ message: "Generating complete system architecture" });
      const workingDir = dirname(document.fileName);
      await execAsync(`node dist/inference-engine/test-cli.js "${document.fileName}" -o "${outputFile}"`, { cwd: workingDir });
    });
    vscode.window.showInformationMessage(`AI-inferred complete system generated: ${outputFile}`);
    const openFile = await vscode.window.showInformationMessage(
      "Open AI-inferred complete system?",
      "Open",
      "Cancel"
    );
    if (openFile === "Open") {
      const inferredDocument = await vscode.workspace.openTextDocument(outputFile);
      await vscode.window.showTextDocument(inferredDocument);
    }
  } catch (error) {
    vscode.window.showErrorMessage(`AI inference failed: ${error.message}`);
  }
}
async function runTestCycleForDocument(document) {
  try {
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    if (!config.get("testing.enableCycle")) {
      vscode.window.showInformationMessage("Test cycle is disabled in settings");
      return;
    }
    await vscode.window.withProgress({
      location: vscode.ProgressLocation.Notification,
      title: "Running test cycle...",
      cancellable: false
    }, async (progress) => {
      progress.report({ message: "Validating \u2192 Processing \u2192 Validating" });
      const workingDir = dirname(document.fileName);
      await execAsync(`"${cliPath}" test cycle "${document.fileName}"`, { cwd: workingDir });
    });
    vscode.window.showInformationMessage("Test cycle completed successfully");
  } catch (error) {
    vscode.window.showErrorMessage(`Test cycle failed: ${error.message}`);
  }
}
async function executeCliCommand(document, commandName) {
  const commandMap = {
    // Single commands (unchanged)
    "validate": "validate",
    "infer": "infer",
    "init": "init",
    "cache": "cache",
    "help": "help",
    "gen": "gen",
    "dev": "dev",
    "test": "test",
    // Grouped commands - map compressed names to CLI format
    "genyaml": "gen yaml",
    "gendiagram": "gen diagram",
    "gendocs": "gen docs",
    "genviews": "gen views",
    "genall": "gen all",
    "devquick": "dev quick",
    "devformat": "dev format",
    "devwatch": "dev watch",
    "testcycle": "test cycle",
    "testbatch": "test batch"
  };
  const cliCommand = commandMap[commandName] || commandName;
  try {
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    const workingDir = dirname(document.fileName);
    const fullCommand = `"${cliPath}" ${cliCommand} "${document.fileName}"`;
    console.log(`[SpecVerse] Executing: ${fullCommand}`);
    await vscode.window.withProgress({
      location: vscode.ProgressLocation.Notification,
      title: `Running SpecVerse ${cliCommand}...`,
      cancellable: false
    }, async (progress) => {
      progress.report({ message: "Processing specification file" });
      const { stdout: stdout2, stderr } = await execAsync(fullCommand, { cwd: workingDir });
      if (stdout2) console.log(`[SpecVerse] stdout:`, stdout2);
      if (stderr) console.log(`[SpecVerse] stderr:`, stderr);
    });
    vscode.window.showInformationMessage(`SpecVerse ${cliCommand} completed successfully`);
  } catch (error) {
    console.log(`[SpecVerse] Command failed:`, error);
    const diagnostics = vscode.languages.createDiagnosticCollection(`specverse-${commandName}`);
    const errors = [];
    const allOutput = ((error.stdout || "") + "\n" + (error.stderr || "")).split("\n");
    allOutput.forEach((line) => {
      line = line.trim();
      if (!line) return;
      let errorMessage = "";
      let severity = vscode.DiagnosticSeverity.Error;
      let lineNumber = 0;
      const numberedErrorMatch = line.match(/^\d+\.\s*(.+)$/);
      if (numberedErrorMatch) {
        errorMessage = numberedErrorMatch[1].trim();
      } else if (line.includes("\u274C") && !line.includes("Validation failed")) {
        errorMessage = line.replace(/❌/g, "").trim();
      } else if (line.includes("Unknown property") || line.includes("should") || line.includes("required")) {
        errorMessage = line;
      } else if (line.includes("/") && line.includes(":")) {
        errorMessage = line;
      } else if (line.includes("\u26A0\uFE0F") || line.includes("Warning:")) {
        errorMessage = line.replace(/⚠️|Warning:/, "").trim();
        severity = vscode.DiagnosticSeverity.Warning;
      } else if (line.includes("Validation failed") || line.includes("Validation Errors:") || line.includes("\u{1F4DD}")) {
        return;
      }
      if (errorMessage) {
        const diagnostic = new vscode.Diagnostic(
          new vscode.Range(lineNumber, 0, lineNumber, Number.MAX_SAFE_INTEGER),
          errorMessage,
          severity
        );
        diagnostic.source = "SpecVerse";
        errors.push(diagnostic);
      }
    });
    if (errors.length > 0) {
      diagnostics.set(document.uri, errors);
      vscode.window.showErrorMessage(`SpecVerse ${cliCommand} failed with ${errors.length} errors. See Problems panel for details.`);
    } else {
      const diagnostic = new vscode.Diagnostic(
        new vscode.Range(0, 0, 0, 0),
        `SpecVerse ${cliCommand} failed: ${error.message}`,
        vscode.DiagnosticSeverity.Error
      );
      diagnostic.source = "SpecVerse";
      diagnostics.set(document.uri, [diagnostic]);
      vscode.window.showErrorMessage(`SpecVerse ${cliCommand} failed: ${error.message}`);
    }
  }
}
async function runMigrateCommand(targetDir) {
  try {
    const config = vscode.workspace.getConfiguration("specverse");
    const cliPath = config.get("cli.path") || "specverse";
    const dryRun = await vscode.window.showQuickPick([
      { label: "Migrate", description: "Apply migration to files", value: false },
      { label: "Dry Run", description: "Preview changes without modifying files", value: true }
    ], {
      placeHolder: "Choose migration mode"
    });
    if (!dryRun) return;
    const dryRunFlag = dryRun.value ? "--dry-run" : "";
    const fullCommand = `"${cliPath}" migrate ${dryRunFlag} "${targetDir}"`;
    console.log(`[SpecVerse] Executing: ${fullCommand}`);
    await vscode.window.withProgress({
      location: vscode.ProgressLocation.Notification,
      title: `Migrating specs to v3.5 format...`,
      cancellable: false
    }, async (progress) => {
      progress.report({ message: dryRun.value ? "Previewing changes..." : "Applying migration..." });
      const { stdout: stdout2, stderr } = await execAsync(fullCommand, { cwd: targetDir });
      const outputChannel = vscode.window.createOutputChannel("SpecVerse Migration");
      outputChannel.clear();
      if (stdout2) outputChannel.appendLine(stdout2);
      if (stderr) outputChannel.appendLine(stderr);
      outputChannel.show();
    });
    vscode.window.showInformationMessage(
      dryRun.value ? "Migration preview complete. Check output for details." : "Migration completed successfully!"
    );
  } catch (error) {
    vscode.window.showErrorMessage(`Migration failed: ${error.message}`);
  }
}
async function runBatchDiagramGeneration() {
  try {
    const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
    if (!workspaceFolder) {
      vscode.window.showErrorMessage("No workspace folder found");
      return;
    }
    await vscode.window.withProgress({
      location: vscode.ProgressLocation.Notification,
      title: "Generating batch diagrams...",
      cancellable: false
    }, async (progress) => {
      progress.report({ message: "Processing all .specly files and generating enhanced diagrams" });
      await execAsync("node scripts/generate-diagrams-batch.js", { cwd: workspaceFolder.uri.fsPath });
    });
    vscode.window.showInformationMessage("Batch diagram generation completed successfully");
  } catch (error) {
    vscode.window.showErrorMessage(`Batch diagram generation failed: ${error.message}`);
  }
}
function deactivate() {
  console.log("SpecVerse v3.5 extension deactivated");
}
export {
  activate,
  deactivate
};
