"""Steps for context_tier_hydration.feature."""

from __future__ import annotations

import shutil
import subprocess
import tempfile
from pathlib import Path

from behave import given, then, when

from cleveragents.application.services.context_tier_hydrator import (
    hydrate_tiers_from_project,
)
from cleveragents.application.services.context_tiers import ContextTierService
from cleveragents.config.settings import Settings


@given("a temp git repo with 2 files for ctx_hydrate")
def step_git_repo(context: object) -> None:
    d = tempfile.mkdtemp(prefix="ctx-hydrate-")
    context.add_cleanup(shutil.rmtree, d, True)
    subprocess.run(["git", "init", "-q"], cwd=d, check=True)
    subprocess.run(["git", "config", "user.name", "T"], cwd=d, check=True)
    subprocess.run(["git", "config", "user.email", "t@t"], cwd=d, check=True)
    Path(d, "main.py").write_text("print('hello')\n")
    Path(d, "utils.py").write_text("def helper(): pass\n")
    subprocess.run(["git", "add", "."], cwd=d, check=True)
    subprocess.run(
        ["git", "-c", "commit.gpgsign=false", "commit", "-q", "-m", "init"],
        cwd=d,
        check=True,
    )
    context.ctx_h_location = d
    context.ctx_h_type = "git-checkout"


@given("a temp dir with 1 text and 1 binary file for ctx_hydrate")
def step_mixed_dir(context: object) -> None:
    d = tempfile.mkdtemp(prefix="ctx-hydrate-")
    context.add_cleanup(shutil.rmtree, d, True)
    Path(d, "readme.md").write_text("# Hello\n")
    Path(d, "image.png").write_bytes(b"\x89PNG\r\n\x1a\n" + b"\x00" * 100)
    context.ctx_h_location = d
    context.ctx_h_type = "fs-directory"


@given("a temp dir with 1 large file for ctx_hydrate")
def step_large_file(context: object) -> None:
    d = tempfile.mkdtemp(prefix="ctx-hydrate-")
    context.add_cleanup(shutil.rmtree, d, True)
    Path(d, "huge.txt").write_text("x" * (300 * 1024))
    context.ctx_h_location = d
    context.ctx_h_type = "fs-directory"


@given("a temp dir with 1 text file for ctx_hydrate")
def step_one_file(context: object) -> None:
    d = tempfile.mkdtemp(prefix="ctx-hydrate-")
    context.add_cleanup(shutil.rmtree, d, True)
    Path(d, "app.py").write_text("app = True\n")
    context.ctx_h_location = d
    context.ctx_h_type = "fs-directory"


@given("a ContextTierService instance for ctx_hydrate")
def step_tier_service(context: object) -> None:
    svc = ContextTierService(settings=Settings())
    context.ctx_h_tier = svc


@when("I hydrate tiers from the resource for ctx_hydrate")
def step_hydrate(context: object) -> None:
    tier = context.ctx_h_tier
    loc = context.ctx_h_location
    rtype = context.ctx_h_type
    count = hydrate_tiers_from_project(
        tier_service=tier,
        project_name="local/test-project",
        resource_id="01TEST00000000000000000001",
        resource_location=loc,
        resource_type=rtype,
    )
    context.ctx_h_count = count


@when("I hydrate tiers from a missing location for ctx_hydrate")
def step_hydrate_missing(context: object) -> None:
    tier = context.ctx_h_tier
    count = hydrate_tiers_from_project(
        tier_service=tier,
        project_name="local/missing",
        resource_id="01TEST00000000000000000002",
        resource_location="/nonexistent/path",
        resource_type="fs-directory",
    )
    context.ctx_h_count = count


def _count_fragments(tier: ContextTierService) -> int:
    """Count fragments using public API."""
    return len(tier.get_scoped_view(["local/test-project"]))


@then("the tier service should have {n:d} fragments for ctx_hydrate")
def step_check_count_plural(context: object, n: int) -> None:
    assert _count_fragments(context.ctx_h_tier) == n


@then("the tier service should have {n:d} fragment for ctx_hydrate")
def step_check_count_singular(context: object, n: int) -> None:
    assert _count_fragments(context.ctx_h_tier) == n


@then('each fragment project_name should be "{name}" for ctx_hydrate')
def step_check_project(context: object, name: str) -> None:
    for frag in context.ctx_h_tier.get_scoped_view(["local/test-project"]):
        assert frag.project_name == name


@then("each fragment resource_id should not be empty for ctx_hydrate")
def step_check_resource_id(context: object) -> None:
    for frag in context.ctx_h_tier.get_scoped_view(["local/test-project"]):
        assert frag.resource_id, f"Empty resource_id on {frag.fragment_id}"


@then("the hydration count should be 0 for ctx_hydrate")
def step_check_zero(context: object) -> None:
    assert context.ctx_h_count == 0
