"""Steps for cancel_worktree_cleanup.feature."""

from __future__ import annotations

import os
import shutil
import subprocess
import tempfile
from pathlib import Path
from unittest.mock import MagicMock, patch

from behave import given, then, when


def _git(args: list[str], cwd: str) -> subprocess.CompletedProcess[str]:
    return subprocess.run(
        ["git", *args],
        cwd=cwd,
        capture_output=True,
        text=True,
        check=True,
        timeout=10,
    )


@given('a temp git project with a worktree sandbox for plan "{plan_id}" for cwc')
def step_create_project_with_worktree(context: object, plan_id: str) -> None:
    d = tempfile.mkdtemp(prefix="cwc-")
    context.add_cleanup(shutil.rmtree, d, True)
    _git(["init", "-q", "-b", "main"], d)
    _git(["config", "user.name", "T"], d)
    _git(["config", "user.email", "t@t"], d)
    _git(["config", "commit.gpgsign", "false"], d)
    Path(d, "file.py").write_text("content\n")
    _git(["add", "."], d)
    _git(["commit", "-q", "-m", "init"], d)

    branch = f"cleveragents/plan-{plan_id}"
    wt_dir = tempfile.mkdtemp(prefix="cwc-wt-")
    context.add_cleanup(shutil.rmtree, wt_dir, True)
    _git(["worktree", "add", "-b", branch, wt_dir, "HEAD"], d)

    context.cwc_repo = d
    context.cwc_wt_dir = wt_dir
    context.cwc_plan_id = plan_id


@given("a mocked service that resolves the project for cwc")
def step_mock_service(context: object) -> None:
    mock_resource = MagicMock()
    mock_resource.resource_type_name = "git-checkout"
    mock_resource.location = context.cwc_repo
    mock_resource.resource_id = "res-cwc-test"

    mock_lr = MagicMock()
    mock_lr.resource_id = "res-cwc-test"

    mock_project = MagicMock()
    mock_project.linked_resources = [mock_lr]

    mock_plan = MagicMock()
    mock_plan.project_links = [MagicMock(project_name="local/cwc-test")]

    mock_service = MagicMock()
    mock_service.get_plan.return_value = mock_plan

    mock_project_repo = MagicMock()
    mock_project_repo.get.return_value = mock_project

    mock_resource_registry = MagicMock()
    mock_resource_registry.show_resource.return_value = mock_resource

    mock_container = MagicMock()
    mock_container.namespaced_project_repo.return_value = mock_project_repo
    mock_container.resource_registry_service.return_value = mock_resource_registry

    context.cwc_service = mock_service
    context.cwc_container = mock_container


@given("a temp git project without any worktree for cwc")
def step_create_clean_project(context: object) -> None:
    d = tempfile.mkdtemp(prefix="cwc-clean-")
    context.add_cleanup(shutil.rmtree, d, True)
    _git(["init", "-q", "-b", "main"], d)
    _git(["config", "user.name", "T"], d)
    _git(["config", "user.email", "t@t"], d)
    _git(["config", "commit.gpgsign", "false"], d)
    Path(d, "file.py").write_text("content\n")
    _git(["add", "."], d)
    _git(["commit", "-q", "-m", "init"], d)
    context.cwc_repo = d
    context.cwc_plan_id = "01TESTNOSANDBOX0000000000"


@given("a mocked service with no linked resources for cwc")
def step_mock_service_no_resources(context: object) -> None:
    mock_plan = MagicMock()
    mock_plan.project_links = []

    mock_service = MagicMock()
    mock_service.get_plan.return_value = mock_plan

    mock_container = MagicMock()

    context.cwc_service = mock_service
    context.cwc_container = mock_container


@when('I call _cleanup_sandbox_for_plan for plan "{plan_id}" for cwc')
def step_call_cleanup(context: object, plan_id: str) -> None:
    from cleveragents.cli.commands.plan import _cleanup_sandbox_for_plan

    with patch(
        "cleveragents.cli.commands.plan.get_container",
        return_value=context.cwc_container,
    ):
        _cleanup_sandbox_for_plan(plan_id, context.cwc_service)

    context.cwc_cleanup_done = True


@then('the branch "{branch_name}" should not exist for cwc')
def step_branch_not_exists(context: object, branch_name: str) -> None:
    result = subprocess.run(
        ["git", "rev-parse", "--verify", f"refs/heads/{branch_name}"],
        cwd=context.cwc_repo,
        capture_output=True,
        check=False,
        timeout=10,
    )
    assert result.returncode != 0, f"Branch {branch_name} still exists"


@then("the worktree directory should not exist for cwc")
def step_worktree_gone(context: object) -> None:
    assert not os.path.exists(context.cwc_wt_dir), (
        f"Worktree directory still exists: {context.cwc_wt_dir}"
    )


@then("the call should complete without error for cwc")
def step_no_error(context: object) -> None:
    assert context.cwc_cleanup_done is True
