import { join } from "node:path";
import { existsSync } from "node:fs";
import { hasComposerDependency } from "../utils.js";
class SymfonyDetector {
  name = "symfony";
  language = "php";
  filePattern = /\.php$/;
  async detect(projectRoot, files) {
    if (files.some((f) => f === "symfony.lock" || f.endsWith("/symfony.lock"))) {
      return true;
    }
    const lockPath = join(projectRoot, "symfony.lock");
    if (existsSync(lockPath)) {
      return true;
    }
    return hasComposerDependency(projectRoot, files, ["symfony/framework-bundle", "symfony/symfony"]);
  }
  async extractRoutes(filePath, content, ctx) {
    const routes = [];
    if (filePath.endsWith("routes.yaml") || filePath.endsWith("routes.yml")) {
      const lines2 = content.split("\n");
      let currentPath = "";
      let currentController = "";
      let currentMethods = [];
      for (const line of lines2) {
        if (/^[a-zA-Z0-9_.-]+:/.test(line)) {
          if (currentPath && currentController) {
            routes.push(...this.createYamlRouteBindings(currentPath, currentController, currentMethods, filePath, ctx));
          }
          currentPath = "";
          currentController = "";
          currentMethods = [];
          continue;
        }
        const pathMatch = line.match(/^\s+path:\s*['"]?([^'"]+)['"]?/);
        if (pathMatch) {
          currentPath = pathMatch[1];
          continue;
        }
        const controllerMatch = line.match(/^\s+controller:\s*['"]?([^'"]+)['"]?/);
        if (controllerMatch) {
          currentController = controllerMatch[1];
          continue;
        }
        const methodsMatch = line.match(/^\s+methods:\s*\[?([^\]]+)\]?/);
        if (methodsMatch) {
          currentMethods = methodsMatch[1].split(",").map((m) => m.trim().replace(/['"]/g, "").toUpperCase());
        }
      }
      if (currentPath && currentController) {
        routes.push(...this.createYamlRouteBindings(currentPath, currentController, currentMethods, filePath, ctx));
      }
      return routes;
    }
    if (!filePath.endsWith(".php")) {
      return [];
    }
    let classPrefix = "";
    const classRouteMatch = content.match(/(?:#\[Route|@Route)\s*\(\s*['"]([^'"]+)['"]/);
    const classDeclMatch = content.match(/\bclass\s+([a-zA-Z0-9_]+)\b/);
    if (!classDeclMatch) return [];
    const className = classDeclMatch[1];
    if (classRouteMatch) {
      const routeIndex = content.indexOf(classRouteMatch[0]);
      const classIndex = content.indexOf(classDeclMatch[0]);
      if (routeIndex !== -1 && routeIndex < classIndex) {
        classPrefix = classRouteMatch[1];
      }
    }
    const lines = content.split("\n");
    let pendingRoute = null;
    for (const line of lines) {
      const routeAttrMatch = line.match(/(?:#\[Route|@Route)\s*\(\s*['"]([^'"]+)['"]/);
      if (routeAttrMatch) {
        const pathVal = routeAttrMatch[1];
        const methods = [];
        const methodsMatch = line.match(/methods\s*[=:]\s*\[?([^\]}]+)\]?/);
        if (methodsMatch) {
          methods.push(...methodsMatch[1].split(",").map((m) => m.trim().replace(/['"{}]+/g, "").toUpperCase()));
        }
        const nameMatch = line.match(/name\s*[=:]\s*['"]([^'"]+)['"]/);
        const routeName = nameMatch ? nameMatch[1] : void 0;
        pendingRoute = { path: pathVal, methods, name: routeName };
        continue;
      }
      if (pendingRoute) {
        const methodDeclMatch = line.match(/\bfunction\s+([a-zA-Z0-9_]+)\s*\(/);
        if (methodDeclMatch) {
          const methodName = methodDeclMatch[1];
          const cleanClassPrefix = classPrefix.replace(/^\/|\/$/g, "");
          const cleanMethodPath = pendingRoute.path.replace(/^\/|\/$/g, "");
          const combinedPath = "/" + [cleanClassPrefix, cleanMethodPath].filter(Boolean).join("/");
          const verbs = pendingRoute.methods.length > 0 ? pendingRoute.methods : ["GET"];
          for (const verb of verbs) {
            routes.push({
              framework: this.name,
              method: verb,
              path: combinedPath,
              handlerFile: filePath,
              handlerSymbol: `${className}::${methodName}`,
              metadata: {
                confidence: "inferred",
                routeType: "server",
                routeName: pendingRoute.name
              }
            });
          }
          pendingRoute = null;
        }
      }
    }
    return routes;
  }
  createYamlRouteBindings(path, controller, methods, filePath, ctx) {
    const bindings = [];
    const parts = controller.split("::");
    const controllerClass = parts[0];
    const controllerMethod = parts[1] || "default";
    const symbol = controllerClass.split("\\").pop() || "Controller";
    let resolvedFile = filePath;
    const resolvedPath = ctx.resolveSymbolToFile(symbol);
    if (resolvedPath) {
      resolvedFile = resolvedPath;
    }
    const verbs = methods.length > 0 ? methods : ["ALL"];
    for (const verb of verbs) {
      bindings.push({
        framework: this.name,
        method: verb,
        path,
        handlerFile: resolvedFile,
        handlerSymbol: `${symbol}::${controllerMethod}`,
        metadata: {
          confidence: "inferred",
          routeType: "server"
        }
      });
    }
    return bindings;
  }
  async extractHooks(filePath, content, ctx) {
    if (!filePath.endsWith(".php")) {
      return [];
    }
    if (!content.includes("getSubscribedEvents")) {
      return [];
    }
    const hooks = [];
    const eventRegex = /['"]([^'"]+)['"]\s*=>\s*(?:['"]([^'"]+)['"]|\[\s*['"]([^'"]+)['"])/g;
    let match;
    while ((match = eventRegex.exec(content)) !== null) {
      const eventName = match[1];
      const handlerSymbol = match[2] || match[3];
      if (handlerSymbol) {
        hooks.push({
          framework: this.name,
          hookName: eventName,
          handlerFile: filePath,
          handlerSymbol,
          hookType: "event_subscriber"
        });
      }
    }
    return hooks;
  }
}
export {
  SymfonyDetector
};
