"""Validation and entry shape for ``PluginContext.register_auxiliary_task``."""

from __future__ import annotations

import logging
from typing import Any, Dict, Optional

logger = logging.getLogger("hermes_cli.plugins")


def build_auxiliary_task_entry(
    me: str, owner_id: str, key: str, *, display_name: str, description: str,
    defaults: Optional[dict[str, Any]], inherit_from: Optional[str], registered: dict[str, dict[str, Any]],
) -> dict[str, Any]:
    """Registry entry for a plugin auxiliary task, or ``ValueError`` for a bad key.

    ``me`` is the manifest name (for messages); ``owner_id`` is the canonical id ``ctx.llm`` is
    bound to, so agent/plugin_llm.py can match it. ``registered`` is the manager's current
    ``_aux_tasks`` (re-registration by the same owner is allowed).
    """
    if not key or not isinstance(key, str):
        raise ValueError(f"Plugin '{me}' tried to register auxiliary task with invalid key {key!r}")
    if not all(c.isalnum() or c == "_" for c in key):
        raise ValueError(f"Plugin '{me}' auxiliary task key {key!r} "
                         f"must contain only alphanumeric characters and underscores")
    from hermes_cli.main_provider_setup import _AUX_TASKS as _BUILTIN_AUX_TASKS
    builtin_aux_keys = {k for k, _name, _desc in _BUILTIN_AUX_TASKS}
    if key in builtin_aux_keys:
        raise ValueError(f"Plugin '{me}' cannot register auxiliary task {key!r} — that key is reserved "
                         f"for a built-in task. Pick a plugin-namespaced key (e.g. '{me}_{key}').")
    existing = registered.get(key)
    if existing is not None and existing.get("plugin") != owner_id:
        raise ValueError(f"Plugin '{me}' cannot register auxiliary task {key!r} — already registered "
                         f"by plugin '{existing.get('plugin')}'")
    # A bad base degrades to "no inheritance" rather than failing the whole plugin load; a
    # self-reference would otherwise only surface at read time, as a cycle.
    if inherit_from is not None and (
            not isinstance(inherit_from, str) or inherit_from == key
            or (inherit_from not in builtin_aux_keys and inherit_from not in registered)):
        logger.warning("Plugin '%s' auxiliary task %r: ignoring inherit_from=%r — not a built-in "
                       "auxiliary task or one already registered by a plugin", me, key, inherit_from)
        inherit_from = None
    # Plugin owns the schema; routing fields are guaranteed present so consumers don't crash.
    # With inheritance the base supplies the shape, so only the plugin's own overrides go here.
    task_defaults = (dict(defaults or {}) if inherit_from else
                     {"provider": "auto", "model": "", "base_url": "", "api_key": "", "timeout": 60,
                      "extra_body": {}, **(defaults or {})})
    entry = {
        "key": key, "display_name": display_name, "description": description,
        "defaults": task_defaults,
        "inherit_from": inherit_from,
        "plugin": owner_id, "plugin_key": owner_id,
    }
    return entry
