import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { QueryTemplates, InlineModifierParser } from "./query-templates.js";
var FrameType = /* @__PURE__ */ ((FrameType2) => {
  FrameType2["TASK"] = "task";
  FrameType2["DEBUG"] = "debug";
  FrameType2["FEATURE"] = "feature";
  FrameType2["ARCHITECTURE"] = "architecture";
  FrameType2["BUG"] = "bug";
  FrameType2["REFACTOR"] = "refactor";
  return FrameType2;
})(FrameType || {});
var FrameStatus = /* @__PURE__ */ ((FrameStatus2) => {
  FrameStatus2["OPEN"] = "open";
  FrameStatus2["CLOSED"] = "closed";
  FrameStatus2["STALLED"] = "stalled";
  return FrameStatus2;
})(FrameStatus || {});
class QueryParser {
  templates = new QueryTemplates();
  inlineParser = new InlineModifierParser();
  shortcuts = /* @__PURE__ */ new Map([
    ["today", { time: { last: "24h" } }],
    [
      "yesterday",
      { time: { last: "48h", since: new Date(Date.now() - 48 * 36e5) } }
    ],
    ["this week", { time: { last: "7d" } }],
    ["last week", { time: { last: "1w" } }],
    ["this month", { time: { last: "30d" } }],
    ["bugs", { frame: { type: ["bug" /* BUG */, "debug" /* DEBUG */] } }],
    ["features", { frame: { type: ["feature" /* FEATURE */] } }],
    ["architecture", { frame: { type: ["architecture" /* ARCHITECTURE */] } }],
    ["refactoring", { frame: { type: ["refactor" /* REFACTOR */] } }],
    ["critical", { frame: { score: { min: 0.8 } } }],
    ["recent", { time: { last: "4h" } }],
    ["stalled", { frame: { status: ["stalled" /* STALLED */] } }],
    ["my work", { people: { owner: ["$current_user"] } }],
    ["team work", { people: { team: "$current_team" } }]
  ]);
  /**
   * Parse natural language query into structured format
   */
  parseNaturalLanguage(query) {
    const templateResult = this.templates.matchTemplate(query);
    if (templateResult) {
      const structured = templateResult;
      if (!structured.output) {
        structured.output = {
          limit: 50,
          sort: "time",
          format: "summary"
        };
      }
      return this.parseStructured(structured);
    }
    const { cleanQuery, modifiers } = this.inlineParser.parse(query);
    const result = {};
    const lowerQuery = cleanQuery.toLowerCase();
    this.parseTimePatterns(lowerQuery, result);
    this.parseTopicPatterns(lowerQuery, result);
    this.parsePeoplePatterns(lowerQuery, result);
    this.expandShortcuts(lowerQuery, result);
    const merged = this.mergeQueries(result, modifiers);
    if (!merged.output) {
      merged.output = {
        limit: 50,
        sort: "time",
        format: "summary"
      };
    } else {
      if (!merged.output.limit) merged.output.limit = 50;
      if (!merged.output.sort) merged.output.sort = "time";
      if (!merged.output.format) merged.output.format = "summary";
    }
    return merged;
  }
  /**
   * Parse structured query with validation
   */
  parseStructured(query) {
    if (query.frame?.score) {
      if (query.frame.score.min !== void 0) {
        query.frame.score.min = Math.max(0, Math.min(1, query.frame.score.min));
      }
      if (query.frame.score.max !== void 0) {
        query.frame.score.max = Math.max(0, Math.min(1, query.frame.score.max));
      }
    }
    if (!query.output) {
      query.output = {
        limit: 50,
        sort: "time",
        format: "full"
      };
    }
    return query;
  }
  /**
   * Parse hybrid query (natural language with structured modifiers)
   */
  parseHybrid(naturalQuery, modifiers) {
    const nlQuery = this.parseNaturalLanguage(naturalQuery);
    return this.mergeQueries(nlQuery, modifiers || {});
  }
  parseTimePatterns(query, result) {
    const lastPattern = /last\s+(\d+)?\s*(day|hour|week|month)s?/i;
    const match = query.match(lastPattern);
    if (match) {
      const quantity = match[1] ? parseInt(match[1]) : 1;
      const unit = match[2].toLowerCase();
      const unitMap = {
        hour: "h",
        day: "d",
        week: "w",
        month: "m"
      };
      result.time = { last: `${quantity}${unitMap[unit]}` };
    }
    for (const [shortcut, value] of this.shortcuts) {
      if (query.includes(shortcut) && value.time) {
        result.time = { ...result.time, ...value.time };
      }
    }
    const datePattern = /(\d{4}-\d{2}-\d{2})|((jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\w*\s+\d{1,2})/i;
    const dateMatch = query.match(datePattern);
    if (dateMatch) {
      try {
        const date = new Date(dateMatch[0]);
        if (!isNaN(date.getTime())) {
          result.time = { ...result.time, specific: date };
        }
      } catch {
      }
    }
  }
  parseTopicPatterns(query, result) {
    const topics = [
      "auth",
      "authentication",
      "login",
      "oauth",
      "database",
      "migration",
      "cache",
      "api",
      "bug",
      "bugs",
      "error",
      "fix",
      "feature",
      "features",
      "test",
      "security",
      "performance"
    ];
    const foundTopics = [];
    for (const topic of topics) {
      const regex = new RegExp(`\\b${topic}\\b`, "i");
      if (regex.test(query)) {
        const normalized = topic === "bugs" ? "bug" : topic === "features" ? "feature" : topic;
        if (!foundTopics.includes(normalized)) {
          foundTopics.push(normalized);
        }
      }
    }
    if (foundTopics.length > 0) {
      result.content = { ...result.content, topic: foundTopics };
    }
    const filePattern = /(\w+\.\w+)|(\*\.\w+)/g;
    const files = query.match(filePattern);
    if (files) {
      result.content = { ...result.content, files };
    }
  }
  parsePeoplePatterns(query, result) {
    const mentionPattern = /@(\w+)/g;
    const mentions = [...query.matchAll(mentionPattern)].map((m) => m[1]);
    if (mentions.length > 0) {
      result.people = { owner: mentions };
    }
    const possessivePattern = /(\w+)'s\s+(work|changes|commits|frames)/i;
    const possMatch = query.match(possessivePattern);
    if (possMatch) {
      const person = possMatch[1].toLowerCase();
      if (!result.people) result.people = {};
      result.people = { ...result.people, owner: [person] };
    }
    if (/\bteam\b/.test(query)) {
      if (!result.people) result.people = {};
      result.people = { ...result.people, team: "$current_team" };
    }
  }
  expandShortcuts(query, result) {
    if (query.includes("critical")) {
      result.frame = {
        ...result.frame,
        score: { min: 0.8 }
      };
    } else if (query.includes("high")) {
      result.frame = {
        ...result.frame,
        score: { min: 0.7 }
      };
    }
    if (query.includes("low priority")) {
      result.frame = {
        ...result.frame,
        score: { max: 0.3 }
      };
    }
    if (query.includes("open") || query.includes("active")) {
      result.frame = {
        ...result.frame,
        status: ["open" /* OPEN */]
      };
    }
    if (query.includes("closed") || query.includes("done")) {
      result.frame = {
        ...result.frame,
        status: ["closed" /* CLOSED */]
      };
    }
  }
  mergeQueries(base, overlay) {
    const merged = {};
    if (base.time || overlay.time) {
      merged.time = { ...base.time, ...overlay.time };
    }
    if (base.content || overlay.content) {
      merged.content = { ...base.content, ...overlay.content };
    }
    if (base.frame || overlay.frame) {
      merged.frame = { ...base.frame, ...overlay.frame };
    }
    if (base.people || overlay.people) {
      merged.people = { ...base.people, ...overlay.people };
    }
    if (base.output || overlay.output) {
      merged.output = { ...base.output, ...overlay.output };
    }
    return merged;
  }
  /**
   * Expand query with synonyms and related terms
   */
  expandQuery(query) {
    const synonyms = {
      auth: ["authentication", "oauth", "login", "session", "jwt"],
      authentication: ["auth", "oauth", "login", "session", "jwt"],
      bug: ["error", "issue", "problem", "fix", "defect"],
      database: ["db", "sql", "postgres", "migration", "schema"],
      test: ["testing", "spec", "unit", "integration", "e2e"]
    };
    if (query.content?.topic) {
      const expandedTopics = new Set(query.content.topic);
      for (const topic of query.content.topic) {
        const syns = synonyms[topic.toLowerCase()];
        if (syns) {
          syns.forEach((s) => expandedTopics.add(s));
        }
      }
      query.content.topic = Array.from(expandedTopics);
    }
    return query;
  }
  /**
   * Main parse method that returns a complete QueryResponse
   */
  parse(query) {
    const original = typeof query === "string" ? query : JSON.stringify(query);
    const interpreted = typeof query === "string" ? this.parseNaturalLanguage(query) : this.parseStructured(JSON.parse(JSON.stringify(query)));
    const validationErrors = this.validateQuery(interpreted);
    const expanded = this.expandQuery(JSON.parse(JSON.stringify(interpreted)));
    const suggestions = this.generateSuggestions(interpreted, validationErrors);
    return {
      original,
      interpreted,
      expanded,
      suggestions,
      validationErrors: validationErrors.length > 0 ? validationErrors : void 0
    };
  }
  /**
   * Validate query for errors and inconsistencies
   */
  validateQuery(query) {
    const errors = [];
    if (query.time) {
      if (query.time.since && query.time.until) {
        if (query.time.since > query.time.until) {
          errors.push('Time filter: "since" date is after "until" date');
        }
      }
      if (query.time.between) {
        if (query.time.between[0] > query.time.between[1]) {
          errors.push('Time filter: Invalid date range in "between"');
        }
      }
    }
    if (query.frame?.score) {
      if (query.frame.score.min !== void 0 && query.frame.score.max !== void 0) {
        if (query.frame.score.min > query.frame.score.max) {
          errors.push(
            "Frame filter: Minimum score is greater than maximum score"
          );
        }
      }
    }
    if (query.frame?.depth) {
      if (query.frame.depth.min !== void 0 && query.frame.depth.max !== void 0) {
        if (query.frame.depth.min > query.frame.depth.max) {
          errors.push(
            "Frame filter: Minimum depth is greater than maximum depth"
          );
        }
      }
    }
    if (query.output?.limit !== void 0) {
      if (query.output.limit < 1 || query.output.limit > 1e3) {
        errors.push("Output limit must be between 1 and 1000");
      }
    }
    return errors;
  }
  /**
   * Generate query suggestions based on the interpreted query
   */
  generateSuggestions(query, errors) {
    const suggestions = [];
    if (!query.time || !query.time.last && !query.time.since && !query.time.between && !query.time.specific) {
      suggestions.push('Try adding a time filter like "last 24h" or "today"');
    }
    if (!query.content?.topic && !query.frame?.type && !query.people && !query.content?.keywords) {
      suggestions.push(
        "Consider filtering by topic, frame type, or people to narrow results"
      );
    }
    if (query.frame?.type?.includes("bug" /* BUG */) && !query.time) {
      suggestions.push("Add a time filter to focus on recent bugs");
    }
    if (query.frame?.score?.min && query.frame.score.min >= 0.8 && !query.frame?.type) {
      suggestions.push(
        "Consider adding frame type filter with high score threshold"
      );
    }
    if (query.time?.last === "24h") {
      suggestions.push('You can use "today" as a shortcut for last 24 hours');
    }
    if (query.frame?.type?.includes("bug" /* BUG */) && query.frame?.type?.includes("debug" /* DEBUG */)) {
      suggestions.push(
        'You can use "bugs" as a shortcut for bug and debug frames'
      );
    }
    if (errors.length > 0) {
      suggestions.push(
        "Please correct the validation errors before running the query"
      );
    }
    return suggestions;
  }
}
export {
  FrameStatus,
  FrameType,
  QueryParser
};
//# sourceMappingURL=query-parser.js.map
