import { MAX_RECOMMENDATIONS, MAX_TESTS_TO_GENERATE } from "./recommendationSections.js";
// .vue and .svelte cannot be route handlers in any framework — always frontend.
const ALWAYS_FRONTEND_EXT = /\.(vue|svelte)$/i;
// .tsx/.jsx are usually UI components but can be Next.js API handlers (pages/api/*.tsx).
const LIKELY_FRONTEND_EXT = /\.(tsx|jsx)$/i;
// Ambiguous extensions need directory context to distinguish frontend from backend.
const AMBIGUOUS_FRONTEND_PATTERN = /\.(tsx?|jsx?|css|scss|less|html?|erb|jsp|asp|jinja2?|twig)$/i;
const API_DIR_PATTERN = /\/(api|routes?|controllers?|routers?|handlers?|endpoints?|server)\//;
const FRONTEND_DIR_PATTERN = /(^|\/)(components?|pages?|views?|layouts?|app|src\/app|frontend|client|public|styles?|templates?)\//i;
/**
 * Returns true if the file path is a frontend file.
 *
 * Three tiers:
 * 1. .vue / .svelte — always frontend; these file types cannot be route handlers.
 * 2. .tsx / .jsx — frontend unless in an API/backend directory (e.g. pages/api/).
 * 3. Ambiguous extensions (.ts, .js, .css, .html, …) — require a recognised
 *    frontend directory AND must not be in an API/backend directory.
 */
export function isFrontendFile(filePath) {
    if (ALWAYS_FRONTEND_EXT.test(filePath))
        return true;
    if (API_DIR_PATTERN.test(filePath))
        return false;
    if (LIKELY_FRONTEND_EXT.test(filePath))
        return true;
    return AMBIGUOUS_FRONTEND_PATTERN.test(filePath) && FRONTEND_DIR_PATTERN.test(filePath);
}
/**
 * Returns true if the file path looks like a test file rather than UI source.
 *
 * Catches:
 *   - Skyramp-generated tests (`*_test.ts`, `*_smoke.ts`, `*_contract.ts`,
 *     `*_fuzz.ts`, `*_integration.ts`, `*_load.ts`, `*_e2e.ts`, `*_ui.ts`)
 *   - Skyramp scenario files (`scenario_*.json`)
 *   - Conventional Vitest/Jest/Playwright spec naming
 *     (`*.spec.{ts,tsx,js,jsx}`, `*.test.{ts,tsx,js,jsx}`)
 *   - Files inside `__tests__/` directories (Jest convention)
 *
 * Used by callers that want to filter test files OUT of frontend-source
 * processing — `isFrontendFile` returns true for `.spec.ts` under a
 * frontend directory because the rule is "tier-3 ambiguous + frontend dir,"
 * but those tests aren't UI source we'd want to ground recommendations in.
 */
export function isTestFile(filePath) {
    return (/(?:_test|_smoke|_contract|_fuzz|_integration|_load|_e2e|_ui)\.[^/]+$/.test(filePath) ||
        /scenario_[^/]+\.json$/.test(filePath) ||
        /\.(spec|test)\.(tsx?|jsx?)$/.test(filePath) ||
        /(?:^|\/)__tests__\//.test(filePath));
}
// ── LLM scope assessment ──────────────────────────────────────────────────────
/**
 * Builds the PR scope assessment section.
 *
 * When `precomputedUIPct` is provided (0 = backend-only, 100 = UI-only) the server
 * has already determined the split unambiguously — skip Steps A–C and emit one line.
 *
 * For mixed PRs (`precomputedUIPct` is undefined, `hasFrontendChanges` is true) skip
 * Steps A–C but keep Step D so the LLM can apply judgment to determine the UI%.
 *
 * Falls back to the full four-step assessment when no precomputed data is available.
 */
export function buildScopeAssessmentSection(maxTotal = MAX_RECOMMENDATIONS, maxGenerate = MAX_TESTS_TO_GENERATE, isUIOnly = false, 
/** Server-determined UI/E2E percentage. `undefined` = mixed PR or unknown. */
precomputedUIPct, 
/** Whether the diff contains frontend files (true ↔ mixed PR when precomputedUIPct is undefined). */
hasFrontendChanges) {
    const effectiveGenerate = Math.min(maxGenerate, maxTotal);
    const additional = Math.max(0, maxTotal - effectiveGenerate);
    // Unambiguous backend-only or UI-only: emit a single Budget Plan line — no LLM counting needed.
    if (precomputedUIPct !== undefined) {
        return `### PR Scope Assessment
Budget Plan: ${maxTotal} total (${effectiveGenerate} generate + ${additional} additional), ${precomputedUIPct}% UI/E2E

Use these exact numbers throughout the rest of the prompt.`;
    }
    // Mixed PR: server can pre-compute the total but not the UI/E2E split — keep Step D.
    if (hasFrontendChanges) {
        return `### PR Scope Assessment — determine UI% before planning recommendations

Budget Plan (total already determined): **${maxTotal} total (${effectiveGenerate} generate + ${additional} additional)**

**Step D — Determine UI vs backend split for the budget above:**
- Non-UI slots are backend tests; start from file-count ratio for UI%, then apply judgment:
  - Pure CSS/style changes inflate the frontend file count without adding test value → reduce UI%
  - Frontend logic bugs (state management, calculation errors, form validation) in the diff → increase UI% even if few frontend files
  - Frontend component calls a changed backend API → an E2E test covers both sides → count toward UI%
  - Frontend files only in \`__tests__/\` or \`.stories.\` → exclude from the ratio

**Append your UI% now** — update the Budget Plan to:
\`Budget Plan: ${maxTotal} total (${effectiveGenerate} generate + ${additional} additional), <ui_pct>% UI/E2E\`

Use these exact numbers throughout the rest of the prompt.`;
    }
    // Fallback (no diff context — full_repo else-branch or test): full four-step assessment.
    const minTotal = Math.min(effectiveGenerate + 1, maxTotal);
    const minAdditional = Math.max(0, minTotal - effectiveGenerate);
    const baselineFormula = `${effectiveGenerate} (generate) + ${minAdditional} (min additional) = ${minTotal}`;
    const stepD = isUIOnly
        ? `**Step D — UI/E2E confirmation (frontend-only PR):**
This is a frontend-only PR — set **100% UI/E2E** in your Budget Plan.
Budget generate slots toward directly recording and generating UI tests; budget additional slots toward more UI/E2E flows derived from the changed components.`
        : `**Step D — Determine UI vs backend split:**
- Backend-only PR (0 frontend files changed or only CSS/copy): **0% UI/E2E** — focus on integration and contract tests
- Frontend-only PR: **100% UI/E2E** — all tests should be UI/E2E
- Mixed PR — non-UI slots are backend tests; start from file-count ratio for UI%, then apply judgment:
  - Pure CSS/style changes inflate the frontend file count without adding test value → reduce UI%
  - Frontend logic bugs (state management, calculation errors, form validation) in the diff → increase UI% even if few frontend files
  - Frontend component calls a changed backend API → an E2E test covers both sides → count toward UI%
  - Frontend files only in \`__tests__/\` or \`.stories.\` → exclude from the ratio`;
    return `### PR Scope Assessment — complete this first, before planning any recommendations

Read the Changed Files list and endpoint changes above, then work through the four steps below. This determines your **Budget Plan** (total count + backend/frontend split) for the rest of the prompt.

**Step A — Classify changed files:**
Count each type from the diff context (ignore generated test files, lock files, and build artifacts):
- **Frontend files**: .vue / .svelte anywhere (always UI components). .tsx / .jsx anywhere except in api/, routes/, routers/, controllers/, handlers/, endpoints/, or server/ directories. .ts / .js / .html / .css / .scss / .less / .erb / .jsp / .asp / .jinja2 / .twig only when in a frontend directory (components/, pages/, views/, layouts/, app/, frontend/, client/, styles/, templates/).
- **Backend files**: route handlers, controllers, services, models, API modules, middleware, config with business logic
- **Non-application** (exclude from test value): CSS-only, copy/string changes, README, CI config with no logic

**Step B — Assess semantic complexity (quality over quantity):**
Weigh changes by their test value, not file count:
- New API endpoint → HIGH test value: needs happy path + at least one error path (contributes ~2 to budget)
- Modified endpoint with formula / business logic change → HIGH: edge cases matter (contributes ~1–2)
- Auth middleware change → CRITICAL: flag for extra security tests regardless of file count
- Frontend state / validation / calculation logic → HIGH for UI tests even if zero backend endpoints changed
- CSS / copy / purely cosmetic changes → LOW: may not justify any new test

**Step C — Determine total recommendation count (${minTotal}–${maxTotal}):**
Start from the baseline formula: *${baselineFormula}*, then adjust:
- **Scale up** for: critical auth/data-integrity changes (+2), complex multi-step business workflows (+1 each), new endpoints with non-trivial validation (+1 each beyond the formula)
- **Scale down** for: style/copy-only changes (may reach minimum of ${minTotal}), already well-tested paths confirmed by existing test list, trivial CRUD with no validation
- **Hard cap**: ${maxTotal}

${stepD}

**State your Budget Plan now** (one line, before any recommendation):
\`Budget Plan: <total> total (<generate> generate + <additional> additional), <ui_pct>% UI/E2E\`

Use these exact numbers throughout the rest of the prompt.`;
}
