"""Steps for sandbox_reexecute_cleanup.feature."""

from __future__ import annotations

import os
import shutil
import subprocess
import tempfile
from pathlib import Path

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 repo with a worktree branch for plan "{plan_id}" for srec')
def step_create_repo_with_branch(context: object, plan_id: str) -> None:
    d = tempfile.mkdtemp(prefix="srec-")
    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)

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

    context.srec_repo = d
    context.srec_wt_dir = wt_dir
    context.srec_branch = branch


@given("a temp git repo without any worktree branches for srec")
def step_create_clean_repo(context: object) -> None:
    d = tempfile.mkdtemp(prefix="srec-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.srec_repo = d


@when('I call cleanup_stale for plan "{plan_id}" for srec')
def step_call_cleanup_stale(context: object, plan_id: str) -> None:
    from cleveragents.infrastructure.sandbox.git_worktree import (
        GitWorktreeSandbox,
    )

    context.srec_cleanup_result = GitWorktreeSandbox.cleanup_stale(
        context.srec_repo,
        plan_id,
    )


@when('I create a fresh sandbox for plan "{plan_id}" for srec')
def step_create_fresh_sandbox(context: object, plan_id: str) -> None:
    from cleveragents.infrastructure.sandbox.git_worktree import (
        GitWorktreeSandbox,
    )

    sandbox = GitWorktreeSandbox(
        resource_id="res-srec-test",
        original_path=context.srec_repo,
    )
    ctx = sandbox.create(plan_id)
    context.srec_fresh_sandbox = ctx.sandbox_path
    context.srec_fresh_sandbox_obj = sandbox
    context.add_cleanup(sandbox.cleanup)


@then('the branch "{branch_name}" should not exist for srec')
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.srec_repo,
        capture_output=True,
        check=False,
        timeout=10,
    )
    assert result.returncode != 0, f"Branch {branch_name} still exists"


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


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


@then("cleanup_stale should return False for srec")
def step_cleanup_returned_false(context: object) -> None:
    assert context.srec_cleanup_result is False, (
        f"Expected False but got {context.srec_cleanup_result}"
    )


@then("the fresh sandbox should be a directory for srec")
def step_fresh_sandbox_is_dir(context: object) -> None:
    assert os.path.isdir(context.srec_fresh_sandbox), (
        f"Fresh sandbox is not a directory: {context.srec_fresh_sandbox}"
    )
