"""Fix generation prompt templates.

Templates for AI-powered fix generation for test failures
and flaky tests.
"""

from __future__ import annotations

# System prompt for fix generation
FIX_GENERATION_SYSTEM_PROMPT = """You are an expert software engineer specializing in fixing test failures and flaky tests.

Your task is to generate minimal, targeted code fixes that address the ROOT CAUSE of failures.

## Core Principles
1. Make the SMALLEST change that fixes the issue — fewer lines = higher confidence
2. NEVER suppress errors without fixing them (no bare except, no try/except: pass)
3. Prefer deterministic solutions over timing-based ones (no time.sleep() fixes)
4. Mock external dependencies rather than making tests depend on live services
5. Ensure the fix doesn't break other tests or change behavior for passing cases
6. Follow the codebase's existing patterns (imports, naming, style)

## Output Format
Use SEARCH/REPLACE blocks to specify changes:
```
path/to/file.py
<<<<<<< SEARCH
old code here (must match exactly)
=======
new code here
>>>>>>> REPLACE
```

## SEARCH/REPLACE Rules
- The SEARCH block must match the original code EXACTLY (whitespace matters)
- Include 2-3 lines of context before and after the change for reliable matching
- Each SEARCH/REPLACE block targets ONE specific change
- If multiple changes are needed, use multiple SEARCH/REPLACE blocks
- Keep each block self-contained and complete

## Anti-Patterns to AVOID
- `time.sleep()` to fix timing issues
- `try: ... except: pass` to hide errors
- `@pytest.mark.flaky(reruns=3)` to mask flakiness
- `sorted(results)` in assertions instead of fixing the data source
- Broad `except Exception` handlers that swallow errors
- Adding retry decorators without fixing the underlying issue

## Fix Description
Keep fix descriptions under 100 words. State: what changed, why, and what root cause it addresses.
"""


# Prompt for generating conservative fixes
CONSERVATIVE_FIX_PROMPT = """Generate a minimal, conservative fix for this error.

## Error
{error_type}: {error_message}

## Location
File: {file_path}
Function: {function_name}

## Code
```python
{code_context}
```

## Root Cause
{root_cause}

## Minimality Constraint
Your fix MUST satisfy: added_lines + removed_lines <= 5
If you need more lines, you are probably not fixing the root cause — think simpler.

Generate a fix that:
1. Makes the absolute smallest change that eliminates the root cause
2. Changes no more than 5 lines total (added + removed)
3. Does NOT add new imports unless absolutely necessary
4. Follows existing code patterns exactly

Output a single SEARCH/REPLACE block:"""


# Prompt for generating RAG-based fixes
RAG_BASED_FIX_PROMPT = """Generate a fix by adapting a pattern from similar successful fixes.

## Current Error
{error_type}: {error_message}

## Similar Past Fixes (for reference only)
{similar_fixes}

## Current Code
```python
{code_context}
```

## Adaptation Instructions
The similar fixes above solved related problems. Do NOT copy them verbatim.
Instead:
1. Identify the PRINCIPLE behind the most relevant fix (what pattern did it apply?)
2. Apply that principle to the current code and error
3. Adapt variable names, function calls, and structure to match the current codebase
4. Verify the adapted fix actually addresses THIS error's root cause

Output a SEARCH/REPLACE block:"""


# Prompt for framework-specific fixes
FRAMEWORK_FIX_PROMPT = """Generate a fix using {framework} best practices.

## Error
{error_type}: {error_message}

## Code
```python
{code_context}
```

## Framework Patterns
{framework_patterns}

Apply the appropriate framework pattern to fix this issue.

Output a SEARCH/REPLACE block:"""


# Prompt for creative exploration
CREATIVE_FIX_PROMPT = """Explore alternative solutions for this error that other strategies would miss.

## Error
{error_type}: {error_message}

## Code
```python
{code_context}
```

## Previous Attempts (if any)
{previous_attempts}

## Your Role
Other strategies will try minimal, conservative changes. YOUR job is DIFFERENT.
You should consider fundamentally different approaches:

- Is the TEST itself wrong? (wrong assertion, wrong setup, testing the wrong thing)
- Is the CODE UNDER TEST flawed? (design issue, not just a bug)
- Does the test need a completely different APPROACH? (different mocking strategy, different assertion)
- Could a STRUCTURAL change solve this? (different data structure, control flow, API)

Do NOT generate a minor variation of a minimal fix. Think bigger.

Generate an innovative fix with explanation:"""


# Prompt for template-based fixes
TEMPLATE_FIX_PROMPT = """Apply the appropriate fix template for this pattern.

## Error Pattern
{error_pattern}

## Available Templates
{templates}

## Code
```python
{code_context}
```

Select and apply the best template:"""


# Prompt for ensemble fix synthesis
ENSEMBLE_FIX_PROMPT = """Synthesize the best fix by combining the strongest elements from multiple candidates.

## Fix Candidates
{fix_candidates}

## Synthesis Instructions
You are combining the BEST ELEMENTS of multiple fixes, not averaging them.

For each candidate:
1. Identify what it gets RIGHT (correct insight, good approach)
2. Identify what it gets WRONG (incomplete, risky, over-engineered)

Then construct a final fix that:
- Includes all the correct insights from the best candidates
- Avoids the mistakes from weaker candidates
- If candidates are fundamentally incompatible, choose the one with strongest evidence
- Remains minimal (the synthesis should NOT be larger than the largest candidate)

## Evaluation Criteria (in priority order)
1. Addresses root cause (not symptoms) — most important
2. Minimal change footprint — smaller is better
3. Doesn't introduce new risks or regressions
4. Follows codebase patterns and conventions

Synthesize the final fix:"""


# Prompt for validating fix quality
VALIDATE_FIX_PROMPT = """Evaluate this fix for quality and correctness. Be critical — only approve fixes that truly solve the problem.

## Fix
```diff
{fix_diff}
```

## Original Error
{error_type}: {error_message}

## Root Cause
{root_cause}

## Evaluation Checklist

1. **Root Cause** (CRITICAL): Does it address the root cause, not just suppress the symptom?
   - Red flags: bare except, try/except pass, retry decorators, sleep additions
   - Green flags: fixes the specific condition that caused the failure

2. **Correctness**: Is it syntactically valid? Will it actually run?
   - Check: matching brackets, valid Python syntax, correct indentation
   - Check: all referenced variables/imports exist

3. **Safety**: Does it introduce any new bugs or regressions?
   - Check: does it change behavior for currently-passing test cases?
   - Check: does it have unintended side effects?

4. **Minimality**: Is it the smallest change that solves the problem?
   - Ideal: 1-5 changed lines
   - Acceptable: 6-10 changed lines with justification
   - Suspicious: 10+ changed lines — likely over-engineered

5. **Style**: Does it follow the codebase's existing conventions?

Rate as: PASS (addresses root cause, correct, minimal) or FAIL (with specific reasons).

Evaluation:"""


def format_conservative_fix_prompt(
    error_type: str,
    error_message: str,
    file_path: str,
    function_name: str,
    code_context: str,
    root_cause: str,
) -> str:
    """Format the conservative fix prompt."""
    return CONSERVATIVE_FIX_PROMPT.format(
        error_type=error_type,
        error_message=error_message,
        file_path=file_path,
        function_name=function_name,
        code_context=code_context,
        root_cause=root_cause,
    )


def format_rag_fix_prompt(
    error_type: str,
    error_message: str,
    similar_fixes: str,
    code_context: str,
) -> str:
    """Format the RAG-based fix prompt."""
    return RAG_BASED_FIX_PROMPT.format(
        error_type=error_type,
        error_message=error_message,
        similar_fixes=similar_fixes,
        code_context=code_context,
    )


def format_framework_fix_prompt(
    error_type: str,
    error_message: str,
    code_context: str,
    framework: str,
    framework_patterns: str,
) -> str:
    """Format the framework-specific fix prompt."""
    return FRAMEWORK_FIX_PROMPT.format(
        error_type=error_type,
        error_message=error_message,
        code_context=code_context,
        framework=framework,
        framework_patterns=framework_patterns,
    )


def format_creative_fix_prompt(
    error_type: str,
    error_message: str,
    code_context: str,
    previous_attempts: str,
) -> str:
    """Format the creative exploration prompt."""
    return CREATIVE_FIX_PROMPT.format(
        error_type=error_type,
        error_message=error_message,
        code_context=code_context,
        previous_attempts=previous_attempts or "None",
    )


def format_ensemble_fix_prompt(
    fix_candidates: str,
) -> str:
    """Format the ensemble synthesis prompt."""
    return ENSEMBLE_FIX_PROMPT.format(
        fix_candidates=fix_candidates,
    )


def format_validation_prompt(
    fix_diff: str,
    error_type: str,
    error_message: str,
    root_cause: str,
) -> str:
    """Format the validation prompt."""
    return VALIDATE_FIX_PROMPT.format(
        fix_diff=fix_diff,
        error_type=error_type,
        error_message=error_message,
        root_cause=root_cause,
    )
