const USER_TYPES = new Set(["int", "e2e", "dal", "load", "pw", "all"]);

export function normalizeTypeValues(values = []) {
  const expanded = [];
  for (const rawValue of values) {
    if (rawValue == null) continue;
    for (const part of String(rawValue).split(",")) {
      const value = part.trim();
      if (!value) continue;
      if (!USER_TYPES.has(value)) {
        throw new Error(
          `Unknown type "${value}". Expected one of: int, e2e, dal, load, pw, all.`
        );
      }
      expanded.push(value);
    }
  }

  if (expanded.length === 0) {
    return ["all"];
  }

  const deduped = [...new Set(expanded)];
  if (deduped.includes("all") && deduped.length > 1) {
    throw new Error(`"--type all" cannot be combined with other types.`);
  }

  const order = ["int", "e2e", "dal", "load", "pw", "all"];
  return deduped.sort((left, right) => order.indexOf(left) - order.indexOf(right));
}

export function isAllTypeSelection(typeValues = []) {
  return typeValues.length === 0 || (typeValues.length === 1 && typeValues[0] === "all");
}

export function parseSuiteSelectors(values = []) {
  const selectors = [];

  for (const rawValue of values) {
    if (rawValue == null) continue;
    for (const part of String(rawValue).split(",")) {
      const value = part.trim();
      if (!value) continue;

      const typeMatch = value.match(/^([a-z]+):(.*)$/);
      if (!typeMatch) {
        selectors.push({ kind: "plain", name: value, raw: value });
        continue;
      }

      const type = typeMatch[1];
      const name = typeMatch[2].trim();
      if (!USER_TYPES.has(type) || type === "all") {
        throw new Error(
          `Unknown suite selector type "${type}". Expected one of: int, e2e, dal, load, pw.`
        );
      }
      if (!name) {
        throw new Error(`Invalid suite selector "${value}". Expected "<type>:<suite-name>".`);
      }

      selectors.push({
        kind: "typed",
        type,
        name,
        raw: `${type}:${name}`,
      });
    }
  }

  return selectors;
}

export function suiteSelectionType(type, framework) {
  if ((framework || "k6") === "playwright") return "pw";
  if (type === "integration") return "int";
  return type;
}

export function matchesSelectedTypes(selectionType, typeValues) {
  return isAllTypeSelection(typeValues) || typeValues.includes(selectionType);
}

export function matchesSuiteSelectors(selectionType, suiteName, selectors = []) {
  if (!selectors || selectors.length === 0) return true;

  return selectors.some((selector) => {
    if (selector.kind === "plain") return selector.name === suiteName;
    return selector.type === selectionType && selector.name === suiteName;
  });
}
