#!/usr/bin/env python3
"""
dna_stream_stub.py - DNA Seed Stream Wrapper

Lightweight stream/inspection wrapper for DNA seeds (text_v1, HXZ1, CDNA).

This module provides:
- DNASeedStream: Unified inspection API for any DNA seed format
- Format detection and auto-loading
- Payload streaming for large seeds
- CLI for quick inspection

WO-DNA-TEXTV1-BRIDGE-01: This replaces the previous stub with real functionality.

Usage:
    from helix_cdc.regrow.dna_stream_stub import DNASeedStream

    # Open and inspect any DNA seed
    stream = DNASeedStream.open("seeds/mistral-regen-487b.hxz")
    info = stream.inspect()
    print(info)

    # Stream payload chunks
    for chunk in stream.chunks(4096):
        process(chunk)

CLI:
    PYTHONPATH=. python3 helix_cdc/regrow/dna_stream_stub.py seeds/mistral-regen-487b.hxz
    PYTHONPATH=. python3 helix_cdc/regrow/dna_stream_stub.py --pretty seeds/shards/*.hxz
"""

from __future__ import annotations

import hashlib
from pathlib import Path
from typing import Any, Dict, Iterable, Union

try:
    from .dna_seed_loader import (
        DNASeedCanonical,
        DNA_FORMAT,
        detect_dna_seed_format,
        load_dna_seed_any,
    )
except ImportError:
    # For CLI usage
    from helix_cdc.regrow.dna_seed_loader import (
        DNASeedCanonical,
        DNA_FORMAT,
        detect_dna_seed_format,
        load_dna_seed_any,
    )


class DNASeedStream:
    """
    Lightweight stream/inspection wrapper for DNA seeds (text_v1, HXZ1, CDNA).

    This does NOT regrow full tensors. It only exposes:
    - header/meta inspection
    - payload length and integrity hash
    - payload chunk streaming

    Use this for inventory, validation, and bridging workflows.
    """

    def __init__(self, seed: DNASeedCanonical):
        """
        Initialize with a pre-loaded canonical seed.

        Use DNASeedStream.open() for convenience.
        """
        self.seed = seed
        self._payload_sha256: str | None = None

    @classmethod
    def open(cls, path: Union[str, Path]) -> "DNASeedStream":
        """
        Open a DNA seed file and return a stream wrapper.

        Auto-detects format (text_v1, hxz1, cdna).

        Args:
            path: Path to .hxz seed file

        Returns:
            DNASeedStream ready for inspection or streaming
        """
        seed = load_dna_seed_any(str(path))
        return cls(seed)

    @property
    def format(self) -> DNA_FORMAT:
        """Return the detected format."""
        return self.seed.format

    @property
    def path(self) -> str:
        """Return the source path."""
        return self.seed.path

    @property
    def payload_sha256(self) -> str:
        """Compute SHA256 of payload (cached)."""
        if self._payload_sha256 is None:
            self._payload_sha256 = hashlib.sha256(self.seed.payload_bytes).hexdigest()
        return self._payload_sha256

    def inspect(self) -> Dict[str, Any]:
        """
        Return a dictionary with seed inspection details.

        Includes:
        - path, format, schema
        - file_size, payload_bytes, payload_sha256
        - meta (format-specific metadata)
        """
        return {
            "path": self.seed.path,
            "format": self.seed.format,
            "schema": self.seed.meta.get("schema", "unknown"),
            "file_size": self.seed.file_size,
            "payload_bytes": len(self.seed.payload_bytes),
            "payload_sha256": self.payload_sha256,
            "meta": self.seed.meta,
        }

    def chunks(self, chunk_size: int = 4096) -> Iterable[bytes]:
        """
        Yield the payload in fixed-size chunks.

        Useful for streaming large payloads without loading all at once
        (though payload is already in memory after open()).

        Args:
            chunk_size: Bytes per chunk (default 4096)

        Yields:
            bytes chunks of payload
        """
        payload = self.seed.payload_bytes
        for i in range(0, len(payload), chunk_size):
            yield payload[i:i + chunk_size]

    def __repr__(self) -> str:
        return (
            f"DNASeedStream(path={self.seed.path!r}, "
            f"format={self.seed.format!r}, "
            f"payload={len(self.seed.payload_bytes)} bytes)"
        )


# =============================================================================
# CLI
# =============================================================================

if __name__ == "__main__":
    import argparse
    import json
    import sys

    parser = argparse.ArgumentParser(
        description="Inspect DNA seeds (text_v1, HXZ1, CDNA)"
    )
    parser.add_argument(
        "paths",
        nargs="+",
        help="Path(s) to DNA seed (.hxz) files"
    )
    parser.add_argument(
        "--pretty", "-p",
        action="store_true",
        help="Pretty-print JSON output"
    )
    parser.add_argument(
        "--json-array",
        action="store_true",
        help="Output all results as a JSON array"
    )

    args = parser.parse_args()

    results = []
    errors = []

    for path in args.paths:
        p = Path(path)
        if not p.exists():
            errors.append({"path": str(p), "error": "File not found"})
            continue

        try:
            stream = DNASeedStream.open(p)
            info = stream.inspect()
            results.append(info)
        except Exception as e:
            errors.append({"path": str(p), "error": str(e)})

    # Output
    if args.json_array:
        output = {"results": results, "errors": errors}
        if args.pretty:
            print(json.dumps(output, indent=2, sort_keys=True))
        else:
            print(json.dumps(output))
    else:
        for info in results:
            if args.pretty:
                print(json.dumps(info, indent=2, sort_keys=True))
            else:
                print(json.dumps(info))

        for err in errors:
            print(f"ERROR: {err['path']}: {err['error']}", file=sys.stderr)

    sys.exit(1 if errors else 0)
