"""Shared helpers for Metadata Overwrite node metadata collection.

Used by both the MetadataOverwriteLM node (execution time) and the
MetadataOverwriteExtractor (hook time) so the conversion/filtering logic
cannot drift between the two paths.
"""

import logging
from typing import Any, Dict

from ..utils.utils import model_patcher_to_name, sampler_object_to_name
from .constants import CLIP_SKIP_SENTINEL, METADATA_OVERWRITE_FIELDS

logger = logging.getLogger(__name__)


def collect_overwrite_params(values: Dict[str, Any]) -> Dict[str, Any]:
    """Convert node input values into non-default overwrite parameters.

    For most fields, a falsy value (empty string, 0) means "not set" and is
    skipped.  clip_skip uses a dedicated sentinel (-25) so that a wired value
    of 0 is preserved.  The ``model`` field accepts either a manual string or
    a wired MODEL (ModelPatcher) connection; in the latter case the source
    model name is extracted from the patcher's ``cached_patcher_init`` and
    stored as a ComfyUI-style relative path.  The ``sampler`` field likewise
    accepts a manual string or a wired SAMPLER (KSAMPLER) connection, from
    which the sampler name is extracted via the sampler function's name.
    """
    result: Dict[str, Any] = {}
    for key in METADATA_OVERWRITE_FIELDS:
        value = values.get(key)
        if key == "model" and not isinstance(value, str):
            value = model_patcher_to_name(value)
            if value is None:
                logger.warning(
                    "Could not extract model name from wired MODEL input "
                    "(no cached_patcher_init); model metadata overwrite skipped"
                )
        elif key == "sampler" and not isinstance(value, str):
            value = sampler_object_to_name(value)
            if value is None:
                logger.warning(
                    "Could not extract sampler name from wired SAMPLER input "
                    "(unrecognized sampler function); sampler metadata overwrite skipped"
                )
        if key == "clip_skip":
            if value != CLIP_SKIP_SENTINEL:
                result[key] = value
        elif value:
            result[key] = value
    return result
