
from pathlib import Path
from typing import Dict

DEFAULT_HOT_STORAGE_LIMIT = 1 << 30  # 1 GiB
DEFAULT_COLD_STORAGE_LIMIT = 10 << 30  # 10 GiB
DEFAULT_INCOMING_PORT = 52780
DEFAULT_LOGGING_RETENTION_DAYS = 90
DEFAULT_PEER_TIMEOUT_SECONDS = 15 * 60  # 15 minutes
DEFAULT_PEER_TIMEOUT_INTERVAL_SECONDS = 10  # 10 seconds
DEFAULT_BOOTSTRAP_RETRY_INTERVAL_SECONDS = 30  # 30 seconds
DEFAULT_SEEDS = ["bootstrap.astreum.org:52780"]


def config_setup(config: Dict = {}):
    """
    Normalize configuration values before the node starts.
    """
    chain_str = config.get("chain")
    if chain_str not in {"main", "test"}:
        chain_str = None
    chain_id_raw = config.get("chain_id")
    if chain_id_raw is None:
        chain_id = 1 if chain_str == "main" else 0
    else:
        try:
            chain_id = int(chain_id_raw)
        except (TypeError, ValueError) as exc:
            raise ValueError(
                f"chain_id must be an integer: {chain_id_raw!r}"
            ) from exc
    if chain_str is None:
        chain_str = "main" if chain_id == 1 else "test"
    config["chain"] = chain_str
    config["chain_id"] = chain_id

    hot_limit_raw = config.get(
        "hot_storage_limit", config.get("hot_storage_default_limit", DEFAULT_HOT_STORAGE_LIMIT)
    )
    try:
        config["hot_storage_limit"] = int(hot_limit_raw)
    except (TypeError, ValueError) as exc:
        raise ValueError(
            f"hot_storage_limit must be an integer: {hot_limit_raw!r}"
        ) from exc

    cold_limit_raw = config.get("cold_storage_limit", DEFAULT_COLD_STORAGE_LIMIT)
    try:
        config["cold_storage_limit"] = int(cold_limit_raw)
    except (TypeError, ValueError) as exc:
        raise ValueError(
            f"cold_storage_limit must be an integer: {cold_limit_raw!r}"
        ) from exc

    cold_path_raw = config.get("cold_storage_path")
    if cold_path_raw:
        try:
            path_obj = Path(cold_path_raw)
            path_obj.mkdir(parents=True, exist_ok=True)
            config["cold_storage_path"] = str(path_obj)
        except OSError:
            config["cold_storage_path"] = None
    else:
        config["cold_storage_path"] = None

    retention_raw = config.get(
        "logging_retention_days",
        config.get("logging_retention", config.get("retention_days", DEFAULT_LOGGING_RETENTION_DAYS)),
    )
    try:
        config["logging_retention_days"] = int(retention_raw)
    except (TypeError, ValueError) as exc:
        raise ValueError(
            f"logging_retention_days must be an integer: {retention_raw!r}"
        ) from exc

    incoming_port_raw = config.get("incoming_port", DEFAULT_INCOMING_PORT)
    try:
        config["incoming_port"] = int(incoming_port_raw)
    except (TypeError, ValueError) as exc:
        raise ValueError(
            f"incoming_port must be an integer: {incoming_port_raw!r}"
        ) from exc

    peer_timeout_raw = config.get("peer_timeout", DEFAULT_PEER_TIMEOUT_SECONDS)
    try:
        peer_timeout = int(peer_timeout_raw)
    except (TypeError, ValueError) as exc:
        raise ValueError(
            f"peer_timeout must be an integer: {peer_timeout_raw!r}"
        ) from exc

    if peer_timeout <= 0:
        raise ValueError("peer_timeout must be a positive integer")

    config["peer_timeout"] = peer_timeout

    interval_raw = config.get("peer_timeout_interval", DEFAULT_PEER_TIMEOUT_INTERVAL_SECONDS)
    try:
        interval = int(interval_raw)
    except (TypeError, ValueError) as exc:
        raise ValueError(
            f"peer_timeout_interval must be an integer: {interval_raw!r}"
        ) from exc

    if interval <= 0:
        raise ValueError("peer_timeout_interval must be a positive integer")

    config["peer_timeout_interval"] = interval

    bootstrap_retry_raw = config.get(
        "bootstrap_retry_interval", DEFAULT_BOOTSTRAP_RETRY_INTERVAL_SECONDS
    )
    try:
        bootstrap_retry_interval = int(bootstrap_retry_raw)
    except (TypeError, ValueError) as exc:
        raise ValueError(
            f"bootstrap_retry_interval must be an integer: {bootstrap_retry_raw!r}"
        ) from exc
    if bootstrap_retry_interval <= 0:
        raise ValueError("bootstrap_retry_interval must be a positive integer")
    config["bootstrap_retry_interval"] = bootstrap_retry_interval

    if "default_seeds" in config:
        default_seeds_raw = config["default_seeds"]
    else:
        default_seeds_raw = DEFAULT_SEEDS

    if isinstance(default_seeds_raw, (list, tuple)):
        config["default_seeds"] = list(default_seeds_raw)
    else:
        raise ValueError("default_seeds must be a list of strings")

    additional_seeds_raw = config.get("additional_seeds", [])
    if isinstance(additional_seeds_raw, (list, tuple)):
        config["additional_seeds"] = list(additional_seeds_raw)
    else:
        raise ValueError("additional_seeds must be a list of strings")

    return config
