"""lint task: run ruff check and produce patches.diff (fix diff or report)."""

from __future__ import annotations

import subprocess

from milco.core.run_context import RunContext
from milco.core.artifacts import write_artifact, ensure_all_artifacts_exist
from milco.tasks.base import FixResult
from milco.tasks.registry import register_task, TaskBase

NO_CHANGES_PLACEHOLDER = (
    "# No fixable lint issues – or run 'ruff check .' for full report.\n"
)
RUFF_NOT_FOUND_MSG = (
    "ruff not found. Install with: pip install ruff or pip install milco[lint]"
)


@register_task("lint")
class LintTask(TaskBase):
    needs_llm = False
    description = "Run ruff check and produce patches.diff (fix diff or report)"

    def fix(self, ctx: RunContext) -> FixResult:
        ctx.ensure_run_dir()
        errors: list[str] = []

        from milco.policy.policy import check_evidence_first

        evidence_path = ctx.artifact_path("evidence.md")
        evidence_text = (
            evidence_path.read_text(encoding="utf-8") if evidence_path.exists() else ""
        )
        ok, msg = check_evidence_first(evidence_text)
        if not ok:
            errors.append(msg)
            ensure_all_artifacts_exist(ctx)
            return FixResult(success=False, applied=False, diff_text="", errors=errors)

        try:
            run_result = subprocess.run(
                ["ruff", "check", "--diff", "."],
                cwd=ctx.repo_root,
                capture_output=True,
                text=True,
                timeout=120,
            )
        except FileNotFoundError:
            errors.append(RUFF_NOT_FOUND_MSG)
            ensure_all_artifacts_exist(ctx)
            return FixResult(success=False, applied=False, diff_text="", errors=errors)

        diff_text = run_result.stdout if run_result.stdout else ""
        if run_result.stderr:
            diff_text = (diff_text + "\n" + run_result.stderr).strip() or diff_text
        if not diff_text.strip():
            diff_text = NO_CHANGES_PLACEHOLDER

        write_artifact(ctx, "patches.diff", diff_text)

        applied = False
        if ctx.can_apply():
            try:
                apply_result = subprocess.run(
                    ["ruff", "check", "--fix", "."],
                    cwd=ctx.repo_root,
                    capture_output=True,
                    text=True,
                    timeout=120,
                )
                applied = apply_result.returncode == 0
            except FileNotFoundError:
                if not errors:
                    errors.append(RUFF_NOT_FOUND_MSG)

        ensure_all_artifacts_exist(ctx)
        return FixResult(
            success=len(errors) == 0,
            applied=applied,
            diff_text=diff_text,
            errors=errors,
        )
