# yaml_emit.py
from typing import Any, Dict, Union
from pathlib import Path
import os

HEADER = "# Generated by HASSL codegen\n"

def ensure_dir(path: Union[str, Path]) -> None:
    Path(path).mkdir(parents=True, exist_ok=True)

def _deep_update(dst: Dict, src: Dict) -> Dict:
    """Recursively merge src into dst (in-place) and return dst."""
    for k, v in src.items():
        if isinstance(v, dict) and isinstance(dst.get(k), dict):
            _deep_update(dst[k], v)
        else:
            dst[k] = v
    return dst

def _load_yaml_or_empty(path: Path) -> Dict:
    if not path.exists():
        return {}
    try:
        import yaml
        data = yaml.safe_load(path.read_text()) or {}
        return data if isinstance(data, dict) else {}
    except Exception:
        # If existing file is not valid YAML, ignore/overwrite
        return {}

def _dump_yaml(
    path: Union[str, Path],
    data: Any,
    *,
    header: bool = True,
    merge: bool = True,
    ensure_sections: bool = False,
) -> None:
    """
    Write YAML to `path`.

    - merge=True: deep-merge into existing file (if any) instead of overwriting.
    - header=True: prepend the standard HASSL header line.
    - ensure_sections=True: guarantee HA helper sections exist (input_text/input_boolean/input_number).

    Backward compatible with previous signature: _dump_yaml(path, data)
    """
    p = Path(path)
    ensure_dir(p.parent)

    out: Dict = {}
    if merge:
        out = _load_yaml_or_empty(p)

    # Deep-merge user data into 'out'
    if isinstance(data, dict):
        _deep_update(out, data)
    else:
        # If non-dict, just replace (can still honor header)
        out = data

    if ensure_sections and isinstance(out, dict):
        out.setdefault("input_text", {})
        out.setdefault("input_boolean", {})
        out.setdefault("input_number", {})

    try:
        import yaml
        body = yaml.safe_dump(out, sort_keys=False)
        p.write_text((HEADER if header else "") + body)
    except Exception:
        # Fallback to JSON if PyYAML not available
        import json
        p.write_text(
            (HEADER if header else "")
            + json.dumps(out, indent=2)
        )
