"""Seed 관리자 - 작업별 Seed 고정 및 추적."""

from __future__ import annotations

import hashlib
import random

from sqlalchemy.orm import Session

from harness.logger import JobRecord


class SeedManager:
    """DXF 파일 해시 기반 결정론적 seed를 생성하고 이력을 관리한다."""

    MAX_SEED = 2**32 - 1

    def get_seed(
        self,
        file_hash: str,
        fixed_seed: int | None = None,
        deterministic: bool = True,
    ) -> int:
        """
        Args:
            file_hash: DXF 파일의 SHA256 해시 앞 16자
            fixed_seed: 사용자가 직접 지정한 seed (None이면 자동)
            deterministic: True면 파일 해시 기반, False면 랜덤
        """
        if fixed_seed is not None:
            return int(fixed_seed) % (self.MAX_SEED + 1)

        if deterministic:
            return self._hash_to_seed(file_hash)

        return random.randint(0, self.MAX_SEED)

    def get_or_create_seed(
        self,
        db: Session,
        job_id: int,
        file_hash: str,
        fixed_seed: int | None = None,
        deterministic: bool = True,
    ) -> int:
        """DB에서 기존 seed를 조회하거나 새로 생성한다."""
        existing = db.query(JobRecord).filter_by(id=job_id).first()
        if existing and existing.seed is not None:
            return existing.seed

        seed = self.get_seed(file_hash, fixed_seed, deterministic)
        if existing:
            existing.seed = seed
            db.commit()
        return seed

    @staticmethod
    def _hash_to_seed(file_hash: str) -> int:
        """파일 해시를 정수 seed로 변환한다."""
        digest = hashlib.sha256(file_hash.encode()).digest()
        return int.from_bytes(digest[:4], "big")

    @staticmethod
    def describe(seed: int) -> str:
        return f"seed={seed} (0x{seed:08X})"
