# qsys/target.py
from __future__ import annotations
from dataclasses import dataclass
from typing import List, Tuple, Dict, Optional
import json
from pathlib import Path


@dataclass(frozen=True)
class Target:
    n_qubits: int
    basis_gates: List[str]
    coupling_map: List[Tuple[int, int]]  # directed edges control → target
    name: str = ""
    durations: Optional[Dict[str, float]] = None  # ns, optional
    error_rates: Optional[Dict[str, float]] = None  # optional

    def to_dict(self) -> dict:
        return {
            "name": self.name or f"{self.n_qubits}q-generic",
            "n_qubits": self.n_qubits,
            "basis_gates": self.basis_gates,
            "coupling_map": self.coupling_map,
            "durations": self.durations,
            "error_rates": self.error_rates,
        }

    def to_json(self, path: str | Path) -> None:
        Path(path).write_text(json.dumps(self.to_dict(), indent=2))

    @staticmethod
    def from_json(path: str | Path) -> "Target":
        data = json.loads(Path(path).read_text())
        return Target(
            n_qubits=data["n_qubits"],
            basis_gates=data["basis_gates"],
            coupling_map=data["coupling_map"],
            name=data.get("name", ""),
            durations=data.get("durations"),
            error_rates=data.get("error_rates"),
        )

    def __str__(self) -> str:
        return f"Target({self.name or 'unnamed'}, {self.n_qubits} qubits, {len(self.coupling_map)} edges)"
