#!/usr/bin/env python3
"""Create the frozen live-execution verification config from production config."""

from __future__ import annotations

import argparse
import hashlib
import json
import os
import tempfile
from pathlib import Path
from typing import Any


def sha256_file(path: Path) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as handle:
        for chunk in iter(lambda: handle.read(1024 * 1024), b""):
            digest.update(chunk)
    return digest.hexdigest()


def require_path(config: dict[str, Any], path: tuple[str, ...], expected: Any) -> None:
    value: Any = config
    for key in path:
        if not isinstance(value, dict) or key not in value:
            raise ValueError(f"missing required config path: {'.'.join(path)}")
        value = value[key]
    if value != expected:
        raise ValueError(
            f"{'.'.join(path)} must be {expected!r}, found {value!r}"
        )


def build_live_config(source: dict[str, Any]) -> dict[str, Any]:
    # JSON round-trip gives an isolated copy without importing third-party code.
    result = json.loads(json.dumps(source))
    require_path(result, ("dry_run",), True)
    require_path(result, ("timeframe",), "5m")
    require_path(result, ("max_open_trades",), 4)
    require_path(result, ("trading_mode",), "futures")
    require_path(result, ("margin_mode",), "isolated")
    require_path(result, ("entry_pricing", "price_side"), "same")
    require_path(result, ("entry_pricing", "use_order_book"), True)
    require_path(result, ("unfilledtimeout", "entry"), 10)
    require_path(result, ("order_types", "stoploss"), "market")
    require_path(result, ("order_types", "stoploss_on_exchange"), True)
    require_path(result, ("force_entry_enable",), True)

    exchange = result.get("exchange")
    if not isinstance(exchange, dict):
        raise ValueError("exchange must be an object")
    if exchange.get("key") not in ("", None) or exchange.get("secret") not in ("", None):
        raise ValueError(
            "source config contains exchange credentials; refuse to inherit them"
        )

    result["dry_run"] = False
    result.pop("dry_run_wallet", None)
    result["force_entry_enable"] = False
    return result


def write_private_json(path: Path, payload: dict[str, Any]) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    descriptor, temporary = tempfile.mkstemp(
        prefix=f".{path.name}.", dir=path.parent
    )
    temporary_path = Path(temporary)
    try:
        with os.fdopen(descriptor, "w", encoding="utf-8") as handle:
            json.dump(payload, handle, ensure_ascii=False, indent=4, sort_keys=True)
            handle.write("\n")
        os.chmod(temporary_path, 0o600)
        os.replace(temporary_path, path)
    finally:
        if temporary_path.exists():
            temporary_path.unlink()


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--source", type=Path, required=True)
    parser.add_argument("--output", type=Path, required=True)
    args = parser.parse_args()
    source = json.loads(args.source.read_text(encoding="utf-8"))
    live = build_live_config(source)
    write_private_json(args.output, live)
    print(
        json.dumps(
            {
                "source_sha256": sha256_file(args.source),
                "output_sha256": sha256_file(args.output),
                "output_mode": oct(args.output.stat().st_mode & 0o777),
                "dry_run": live["dry_run"],
                "force_entry_enable": live["force_entry_enable"],
                "dry_run_wallet_present": "dry_run_wallet" in live,
                "timeframe": live["timeframe"],
                "max_open_trades": live["max_open_trades"],
                "margin_mode": live["margin_mode"],
                "entry_price_side": live["entry_pricing"]["price_side"],
                "stoploss_on_exchange": live["order_types"][
                    "stoploss_on_exchange"
                ],
            },
            ensure_ascii=False,
            sort_keys=True,
        )
    )
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
