#
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
"""
Programmatic table generation utilities to eliminate duplication.

This module provides utilities to generate reverse mappings and derived tables
from the primary forward mapping tables, ensuring single source of truth and
reducing maintenance overhead.
"""

from __future__ import annotations

from typing import Any
from hrw4u.states import SectionType


class TableGenerator:
    """Generates derived tables and reverse mappings from primary tables."""

    def __init__(self) -> None:
        pass

    @staticmethod
    def _clean_tag(tag: str) -> str:
        """Extract clean tag name from %{TAG:payload} format."""
        return tag.strip().removeprefix('%{').removesuffix('}').split(':')[0]

    def generate_ip_mapping(self) -> dict[str, str]:
        """Generate IP payload to identifier mapping from CONDITION_MAP."""
        from hrw4u.tables import CONDITION_MAP

        ip_mapping = {}
        for condition_key, params in CONDITION_MAP.items():
            tag = params.target if params else None
            reverse_info = params.rev if params else None
            if reverse_info and reverse_info.get("reverse_tag") == "IP":
                payload = reverse_info.get("reverse_payload")
                if payload:
                    ip_mapping[payload] = condition_key
        return ip_mapping

    def generate_status_target_mapping(self) -> dict[frozenset[SectionType], str]:
        """Generate status target mappings based on section restrictions."""
        return {
            frozenset({SectionType.REMAP, SectionType.SEND_RESPONSE}): "inbound.status",
            frozenset({SectionType.PRE_REMAP, SectionType.READ_REQUEST, SectionType.SEND_REQUEST,
                       SectionType.READ_RESPONSE}): "outbound.status"
        }

    def generate_context_mappings(self) -> dict[str, dict[SectionType | frozenset[SectionType], str]]:
        """Generate context type mappings for headers, URLs, etc."""
        return {
            "HEADER_CONTEXT_MAP":
                {
                    SectionType.REMAP: "inbound.req.",
                    frozenset({SectionType.PRE_REMAP, SectionType.READ_REQUEST, SectionType.SEND_REQUEST}): "outbound.req.",
                    SectionType.READ_RESPONSE: "outbound.resp."
                },
            "URL_CONTEXT_MAP":
                {
                    SectionType.REMAP: "inbound.url.",
                    frozenset({SectionType.PRE_REMAP, SectionType.READ_REQUEST, SectionType.SEND_REQUEST}): "outbound.url."
                }
        }

    def generate_ambiguous_tag_resolution(self) -> dict[str, dict[str, Any]]:
        """Generate ambiguous tag resolution mappings."""
        return {
            "STATUS":
                {
                    "outbound_sections":
                        frozenset(
                            {SectionType.PRE_REMAP, SectionType.READ_REQUEST, SectionType.SEND_REQUEST, SectionType.READ_RESPONSE}),
                    "outbound_result": "outbound.status",
                    "inbound_result": "inbound.status"
                },
            "METHOD":
                {
                    "outbound_sections": frozenset({SectionType.SEND_REQUEST}),
                    "outbound_result": "outbound.method",
                    "inbound_result": "inbound.method"
                }
        }

    def generate_complete_reverse_resolution_map(self) -> dict[str, Any]:
        """Generate the complete reverse resolution map.

        Combines all individual mapping generators into a single structure.
        """
        reverse_map = {}

        # Add IP mappings
        reverse_map["IP"] = self.generate_ip_mapping()

        # Add ambiguous tag resolution
        ambiguous_mappings = self.generate_ambiguous_tag_resolution()
        for tag, mapping in ambiguous_mappings.items():
            reverse_map[tag] = mapping

        # Add status target mappings
        reverse_map["STATUS_TARGETS"] = self.generate_status_target_mapping()

        # Add context mappings
        context_mappings = self.generate_context_mappings()
        for name, mapping in context_mappings.items():
            reverse_map[name] = mapping

        # Add context type mappings
        from hrw4u.tables import CONTEXT_TYPE_MAP, FALLBACK_TAG_MAP
        reverse_map["CONTEXT_TYPE_MAP"] = CONTEXT_TYPE_MAP.copy()

        # Add fallback tag mappings
        reverse_map["FALLBACK_TAG_MAP"] = FALLBACK_TAG_MAP.copy()

        return reverse_map


# Singleton instance for global use
_table_generator = TableGenerator()


def get_complete_reverse_resolution_map() -> dict[str, Any]:
    """Get the complete generated reverse resolution map."""
    return _table_generator.generate_complete_reverse_resolution_map()
