"""Workspace creation and management."""

from dataclasses import dataclass
from pathlib import Path
import json
import subprocess
from typing import Optional

from forge.behavior import BehaviorSpec
from suite.definition import BenchmarkSuite


@dataclass
class TaskMetadata:
    """Metadata stored in .janus-task.json"""
    suite_id: str
    behavior_id: str
    behavior_name: str
    behavior_description: str
    threshold: float
    rubric: dict[int, str]
    workspace_path: str
    initialized_at: str  # ISO8601
    disconfirmers: list[str] = None  # Evidence that would disconfirm the behavior
    taxonomy_code: str = ""  # Taxonomy classification code

    def __post_init__(self):
        if self.disconfirmers is None:
            self.disconfirmers = []

    def to_dict(self) -> dict:
        return {
            "suite_id": self.suite_id,
            "behavior_id": self.behavior_id,
            "behavior_name": self.behavior_name,
            "behavior_description": self.behavior_description,
            "threshold": self.threshold,
            "rubric": self.rubric,
            "workspace_path": self.workspace_path,
            "initialized_at": self.initialized_at,
            "disconfirmers": self.disconfirmers,
            "taxonomy_code": self.taxonomy_code,
        }

    @classmethod
    def from_dict(cls, data: dict) -> "TaskMetadata":
        # Handle legacy metadata files without new fields
        data.setdefault("disconfirmers", [])
        data.setdefault("taxonomy_code", "")
        return cls(**data)


def init_workspace(
    target_dir: Path,
    suite: BenchmarkSuite,
    behavior: BehaviorSpec,
) -> TaskMetadata:
    """
    Initialize a task workspace for outcome-based benchmarking.

    Creates:
    - .janus-task.json (task metadata)
    - src/ directory with starter code
    - tests/ directory with test files
    - README.md with task instructions
    - Initializes git repo

    Returns:
        TaskMetadata for the initialized workspace
    """
    from datetime import datetime, timezone

    target_dir.mkdir(parents=True, exist_ok=True)

    # Create task metadata
    metadata = TaskMetadata(
        suite_id=suite.suite_id,
        behavior_id=behavior.behavior_id,
        behavior_name=behavior.name,
        behavior_description=behavior.description,
        threshold=behavior.threshold,
        rubric=behavior.rubric,
        workspace_path=str(target_dir.resolve()),
        initialized_at=datetime.now(timezone.utc).isoformat(),
        disconfirmers=behavior.disconfirmers,
        taxonomy_code=behavior.taxonomy_code,
    )

    # Write metadata file
    metadata_file = target_dir / ".janus-task.json"
    metadata_file.write_text(json.dumps(metadata.to_dict(), indent=2))

    # Create directories
    (target_dir / "src").mkdir(exist_ok=True)
    (target_dir / "tests").mkdir(exist_ok=True)

    # Copy scaffold files for this behavior
    _copy_scaffold(target_dir, behavior.behavior_id)

    # Create README
    readme = target_dir / "README.md"
    readme.write_text(_generate_readme(behavior))

    # Initialize git repo
    _init_git(target_dir)

    return metadata


def _copy_scaffold(target_dir: Path, behavior_id: str) -> None:
    """Copy scaffold files for the given behavior."""
    scaffold_dir = Path(__file__).parent / "templates" / behavior_id

    if not scaffold_dir.exists():
        # Use default scaffold if behavior-specific not found
        scaffold_dir = Path(__file__).parent / "templates" / "default"

    if scaffold_dir.exists():
        import shutil
        for item in scaffold_dir.iterdir():
            if item.is_file():
                dest = target_dir / item.name
                shutil.copy(item, dest)
            elif item.is_dir():
                dest = target_dir / item.name
                shutil.copytree(item, dest, dirs_exist_ok=True)


def _generate_readme(behavior: BehaviorSpec) -> str:
    """Generate README.md for the task."""
    rubric_lines = "\n".join(
        f"| {score} | {desc} |"
        for score, desc in sorted(behavior.rubric.items())
    )

    return f"""# Janus Labs Task: {behavior.name}

## Behavior ID
`{behavior.behavior_id}`

## Description
{behavior.description}

## Scoring Rubric

| Score | Criteria |
|-------|----------|
{rubric_lines}

**Minimum passing score:** {behavior.threshold}

## Instructions

1. Open this workspace in VS Code
2. Use your AI agent of choice (Claude Code, Copilot, Gemini CLI, etc.)
3. Complete the task described above
4. When done, run: `janus score` from this directory

## What Gets Measured

- **Git diff**: What files were changed and how
- **Test results**: Did the tests pass?
- **Outcome quality**: Scored against the rubric above

---
*Generated by Janus Labs*
"""


def _init_git(target_dir: Path) -> None:
    """Initialize git repo and create initial commit."""
    try:
        subprocess.run(
            ["git", "init"],
            cwd=str(target_dir),
            capture_output=True,
            check=True,
        )
        subprocess.run(
            ["git", "add", "-A"],
            cwd=str(target_dir),
            capture_output=True,
            check=True,
        )
        subprocess.run(
            ["git", "commit", "-m", "Initial scaffold"],
            cwd=str(target_dir),
            capture_output=True,
            check=True,
        )
    except (FileNotFoundError, subprocess.CalledProcessError):
        pass  # Git not available or failed - continue without


def load_task_metadata(workspace_dir: Path) -> Optional[TaskMetadata]:
    """Load task metadata from workspace."""
    metadata_file = workspace_dir / ".janus-task.json"
    if not metadata_file.exists():
        return None

    data = json.loads(metadata_file.read_text())
    return TaskMetadata.from_dict(data)
