"""
Kong API Gateway provider implementation.

Generates Kong declarative configuration (DB-less mode) in YAML format
with support for services, routes, and plugin-based transformations.
"""

import json
import logging
import os
from typing import Any, Dict, List, Optional

import requests
import yaml

from ..config import (
    ActiveHealthCheck,
    ApiKeyConfig,
    AuthenticationConfig,
    BasicAuthConfig,
    Config,
    CORSPolicy,
    GlobalConfig,
    HeaderManipulation,
    HealthCheckConfig,
    JwtConfig,
    LoadBalancerConfig,
    PassiveHealthCheck,
    RateLimitConfig,
    Route,
    Service,
    Upstream,
    UpstreamTarget,
)
from ..provider import Provider

logger = logging.getLogger(__name__)


class KongProvider(Provider):
    """Kong API Gateway provider.

    Generates declarative configuration for Kong Gateway in DB-less mode.
    Kong is a plugin-based API gateway with extensive enterprise features
    and a rich ecosystem of plugins.

    Output Format:
        YAML file in Kong Declarative Configuration format (v3.0):
        - _format_version: Version identifier
        - services: Service definitions with routes
        - routes: Path-based routing rules
        - plugins: Request transformer and other plugins

    Transformations:
        Implemented using Kong's request-transformer plugin.
        Default values are added as custom headers (x-default-*).
        Note: Computed fields (UUID, timestamp) are not natively supported
        and would require custom plugin development.

    gRPC Support:
        Native support via protocol: grpc in service definitions.
        Automatic HTTP/2 handling by Kong.

    Limitations:
        - Computed fields require custom plugins
        - Defaults added as headers, not body fields
        - Advanced transformations need Lua plugins

    Example:
        >>> provider = KongProvider()
        >>> provider.name()
        'kong'
        >>> config = Config.from_yaml("gateway.yaml")
        >>> output = provider.generate(config)
        >>> "_format_version:" in output
        True

    See Also:
        https://docs.konghq.com/gateway/latest/production/deployment-topologies/db-less-and-declarative-config/
    """

    def name(self) -> str:
        """Return provider name.

        Returns:
            str: "kong"
        """
        return "kong"

    def validate(self, config: Config) -> bool:
        """Validate configuration for Kong.

        Kong has minimal validation requirements. Most configurations
        are accepted and validated by Kong at runtime.

        Args:
            config: Configuration to validate

        Returns:
            True (Kong validates at runtime)

        Example:
            >>> provider = KongProvider()
            >>> config = Config(...)
            >>> provider.validate(config)
            True
        """
        logger.debug(f"Validating Kong configuration: {len(config.services)} services")
        return True

    def generate(self, config: Config) -> str:
        """Generate Kong declarative configuration in YAML format.

        Creates a Kong declarative config file (v3.0) with services,
        routes, and transformation plugins.

        Configuration Structure:
            - _format_version: '3.0'
            - services: Service and route definitions
            - plugins: Global and service-specific plugins

        Args:
            config: Configuration object containing services

        Returns:
            Complete Kong declarative YAML configuration

        Example:
            >>> provider = KongProvider()
            >>> config = Config.from_yaml("config.yaml")
            >>> yaml_output = provider.generate(config)
            >>> "services:" in yaml_output
            True
            >>> "routes:" in yaml_output
            True
        """
        logger.info(f"Generating Kong configuration for {len(config.services)} services")
        output = []
        output.append("# Kong Declarative Configuration Generated by GAL")
        output.append("_format_version: '3.0'")
        output.append("")

        # Global plugins for logging and metrics
        global_plugins = []
        if config.global_config and config.global_config.logging:
            global_plugins.extend(self._generate_kong_logging_plugins(config.global_config.logging))
        if config.global_config and config.global_config.metrics:
            global_plugins.extend(self._generate_kong_metrics_plugins(config.global_config.metrics))

        if global_plugins:
            output.append("plugins:")
            for plugin in global_plugins:
                output.append(f"- name: {plugin['name']}")
                if plugin.get("config"):
                    output.append("  config:")
                    for key, value in plugin["config"].items():
                        if isinstance(value, bool):
                            output.append(f"    {key}: {str(value).lower()}")
                        elif isinstance(value, (list, dict)):
                            output.append(f"    {key}: {value}")
                        else:
                            output.append(f"    {key}: {value}")
            output.append("")

        # Generate upstreams first (if needed for load balancing or health checks)
        upstreams_needed = []
        for service in config.services:
            if (
                service.upstream.targets
                or service.upstream.health_check
                or service.upstream.load_balancer
            ):
                upstreams_needed.append(service)

        if upstreams_needed:
            output.append("upstreams:")
            for service in upstreams_needed:
                self._generate_kong_upstream(service, output)
            output.append("")

        output.append("services:")

        for service in config.services:
            output.append(f"- name: {service.name}")
            if service.type == "grpc":
                output.append("  protocol: grpc")
            else:
                output.append("  protocol: http")

            # If using upstream (for LB/HC), reference it; otherwise use direct host/port
            if service in upstreams_needed:
                output.append(f"  host: {service.name}_upstream")
            else:
                output.append(f"  host: {service.upstream.host}")
                output.append(f"  port: {service.upstream.port}")

            # Add timeout configuration (from route or WebSocket config)
            timeout_configured = False
            for route in service.routes:
                if route.timeout:
                    # Kong uses milliseconds for timeouts
                    connect_ms = self._parse_kong_duration(route.timeout.connect) * 1000
                    read_ms = self._parse_kong_duration(route.timeout.read) * 1000
                    send_ms = self._parse_kong_duration(route.timeout.send) * 1000
                    output.append(f"  connect_timeout: {connect_ms}")
                    output.append(f"  read_timeout: {read_ms}")
                    output.append(f"  write_timeout: {send_ms}")
                    timeout_configured = True
                    break
                elif route.websocket and route.websocket.enabled:
                    ws = route.websocket
                    # Kong uses milliseconds for timeouts
                    timeout_ms = self._parse_kong_duration(ws.idle_timeout) * 1000
                    output.append(f"  read_timeout: {timeout_ms}")
                    output.append(f"  write_timeout: {timeout_ms}")
                    timeout_configured = True
                    break

            # Add retry configuration if specified
            for route in service.routes:
                if route.retry and route.retry.enabled:
                    output.append(f"  retries: {route.retry.attempts}")
                    break

            output.append("  routes:")

            for route in service.routes:
                output.append(f"  - name: {service.name}_route")
                output.append("    paths:")
                output.append(f"    - {route.path_prefix}")
                if route.methods:
                    output.append("    methods:")
                    for method in route.methods:
                        output.append(f"    - {method}")

                # Collect plugins for this route
                route_plugins = []

                # Add authentication plugin if configured
                if route.authentication and route.authentication.enabled:
                    auth = route.authentication
                    if auth.type == "basic":
                        route_plugins.append(
                            {"name": "basic-auth", "config": {"hide_credentials": True}}
                        )
                    elif auth.type == "api_key":
                        key_name = auth.api_key.key_name if auth.api_key else "X-API-Key"
                        in_location = auth.api_key.in_location if auth.api_key else "header"
                        route_plugins.append(
                            {
                                "name": "key-auth",
                                "config": {
                                    "key_names": [key_name],
                                    "key_in_header": in_location == "header",
                                    "key_in_query": in_location == "query",
                                    "hide_credentials": True,
                                },
                            }
                        )
                    elif auth.type == "jwt":
                        jwt_config = {}
                        if auth.jwt:
                            if auth.jwt.issuer:
                                jwt_config["claims_to_verify"] = ["iss"]
                            if auth.jwt.audience:
                                jwt_config["claims_to_verify"] = jwt_config.get(
                                    "claims_to_verify", []
                                ) + ["aud"]
                        route_plugins.append(
                            {"name": "jwt", "config": jwt_config if jwt_config else {}}
                        )

                # Add rate limiting plugin if configured
                if route.rate_limit and route.rate_limit.enabled:
                    route_plugins.append(
                        {
                            "name": "rate-limiting",
                            "config": {
                                "second": route.rate_limit.requests_per_second,
                                "policy": "local",
                                "fault_tolerant": True,
                                "hide_client_headers": False,
                            },
                        }
                    )

                # Add header manipulation plugins if configured
                if route.headers:
                    headers = route.headers
                    # Request header manipulation
                    if headers.request_add or headers.request_set or headers.request_remove:
                        req_config = {}
                        if headers.request_add:
                            req_config["add"] = {
                                "headers": [f"{k}:{v}" for k, v in headers.request_add.items()]
                            }
                        if headers.request_set:
                            req_config["replace"] = {
                                "headers": [f"{k}:{v}" for k, v in headers.request_set.items()]
                            }
                        if headers.request_remove:
                            req_config["remove"] = {"headers": headers.request_remove}
                        route_plugins.append({"name": "request-transformer", "config": req_config})

                    # Response header manipulation
                    if headers.response_add or headers.response_set or headers.response_remove:
                        resp_config = {}
                        if headers.response_add:
                            resp_config["add"] = {
                                "headers": [f"{k}:{v}" for k, v in headers.response_add.items()]
                            }
                        if headers.response_set:
                            resp_config["replace"] = {
                                "headers": [f"{k}:{v}" for k, v in headers.response_set.items()]
                            }
                        if headers.response_remove:
                            resp_config["remove"] = {"headers": headers.response_remove}
                        route_plugins.append(
                            {"name": "response-transformer", "config": resp_config}
                        )

                # Add CORS plugin if configured
                if route.cors and route.cors.enabled:
                    cors = route.cors
                    cors_config = {
                        "origins": cors.allowed_origins,
                        "methods": cors.allowed_methods,
                        "headers": cors.allowed_headers,
                        "credentials": cors.allow_credentials,
                        "max_age": cors.max_age,
                    }
                    if cors.expose_headers:
                        cors_config["exposed_headers"] = cors.expose_headers
                    route_plugins.append({"name": "cors", "config": cors_config})

                # Add body transformation plugins if configured
                if route.body_transformation and route.body_transformation.enabled:
                    bt = route.body_transformation

                    # Request body transformation
                    if bt.request:
                        req_bt_config = {}

                        # Add fields to request body
                        if bt.request.add_fields:
                            add_fields = []
                            for key, value in bt.request.add_fields.items():
                                # Convert template variables
                                if value == "{{uuid}}":
                                    # Kong doesn't support UUID generation natively in request-transformer
                                    # Use a placeholder that could be replaced by custom plugin
                                    add_fields.append(f"{key}:$(uuid())")
                                elif value == "{{now}}" or value == "{{timestamp}}":
                                    # Kong doesn't support timestamp generation natively
                                    add_fields.append(f"{key}:$(date())")
                                else:
                                    add_fields.append(f"{key}:{value}")
                            req_bt_config["add"] = {"json": add_fields}

                        # Remove fields from request body
                        if bt.request.remove_fields:
                            req_bt_config["remove"] = {"json": bt.request.remove_fields}

                        # Rename fields (requires custom Lua plugin for full support)
                        # For now, we document this as a limitation
                        if bt.request.rename_fields:
                            logger.warning(
                                f"Request body field renaming configured for {service.name}/{route.path_prefix}, "
                                "but Kong's request-transformer plugin does not natively support field renaming. "
                                "Consider using a custom Lua plugin or post-function plugin for this functionality."
                            )

                        if req_bt_config:
                            route_plugins.append(
                                {"name": "request-transformer", "config": req_bt_config}
                            )

                    # Response body transformation
                    if bt.response:
                        resp_bt_config = {}

                        # Filter (remove) sensitive fields from response
                        if bt.response.filter_fields:
                            resp_bt_config["remove"] = {"json": bt.response.filter_fields}

                        # Add metadata fields to response
                        if bt.response.add_fields:
                            add_fields = []
                            for key, value in bt.response.add_fields.items():
                                # Convert template variables
                                if value == "{{uuid}}":
                                    add_fields.append(f"{key}:$(uuid())")
                                elif value == "{{now}}" or value == "{{timestamp}}":
                                    add_fields.append(f"{key}:$(date())")
                                else:
                                    add_fields.append(f"{key}:{value}")
                            resp_bt_config["add"] = {"json": add_fields}

                        if resp_bt_config:
                            route_plugins.append(
                                {"name": "response-transformer", "config": resp_bt_config}
                            )

                # Circuit Breaker: Kong does not have native circuit breaker support.
                # Third-party plugins exist (e.g., kong-circuit-breaker by Dream11),
                # but are not part of Kong's official plugin ecosystem.
                # For production use, consider using Envoy, APISIX, or Traefik which
                # provide native circuit breaker functionality.
                if route.circuit_breaker and route.circuit_breaker.enabled:
                    logger.warning(
                        f"Circuit breaker configured for route {service.name}/{route.path_prefix}, "
                        "but Kong does not have native circuit breaker support. "
                        "Consider using kong-circuit-breaker plugin or switch to a provider with native support."
                    )

                # Write all route plugins
                if route_plugins:
                    output.append("    plugins:")
                    for plugin in route_plugins:
                        output.append(f"    - name: {plugin['name']}")
                        if plugin["config"]:
                            output.append("      config:")
                            for key, value in plugin["config"].items():
                                if isinstance(value, bool):
                                    output.append(f"        {key}: {str(value).lower()}")
                                elif isinstance(value, list):
                                    output.append(f"        {key}:")
                                    for item in value:
                                        # Quote wildcard * to avoid YAML alias interpretation
                                        if item == "*":
                                            output.append(f"        - '*'")
                                        else:
                                            output.append(f"        - {item}")
                                else:
                                    output.append(f"        {key}: {value}")

            # Add transformation plugins if enabled
            if service.transformation and service.transformation.enabled:
                output.append("  plugins:")

                # Handle defaults (legacy behavior - add as headers)
                if service.transformation.defaults:
                    output.append("  - name: request-transformer")
                    output.append("    config:")
                    output.append("      add:")
                    output.append("        headers:")
                    for key, value in service.transformation.defaults.items():
                        output.append(f"        - x-default-{key}: '{value}'")

                # Handle service-level header manipulation
                if service.transformation.headers:
                    headers = service.transformation.headers
                    # Request header manipulation
                    if headers.request_add or headers.request_set or headers.request_remove:
                        output.append("  - name: request-transformer")
                        output.append("    config:")
                        if headers.request_add:
                            output.append("      add:")
                            output.append("        headers:")
                            for key, value in headers.request_add.items():
                                output.append(f"        - {key}: '{value}'")
                        if headers.request_set:
                            output.append("      replace:")
                            output.append("        headers:")
                            for key, value in headers.request_set.items():
                                output.append(f"        - {key}: '{value}'")
                        if headers.request_remove:
                            output.append("      remove:")
                            output.append("        headers:")
                            for header_name in headers.request_remove:
                                output.append(f"        - {header_name}")

                    # Response header manipulation
                    if headers.response_add or headers.response_set or headers.response_remove:
                        output.append("  - name: response-transformer")
                        output.append("    config:")
                        if headers.response_add:
                            output.append("      add:")
                            output.append("        headers:")
                            for key, value in headers.response_add.items():
                                output.append(f"        - {key}: '{value}'")
                        if headers.response_set:
                            output.append("      replace:")
                            output.append("        headers:")
                            for key, value in headers.response_set.items():
                                output.append(f"        - {key}: '{value}'")
                        if headers.response_remove:
                            output.append("      remove:")
                            output.append("        headers:")
                            for header_name in headers.response_remove:
                                output.append(f"        - {header_name}")

            output.append("")

        result = "\n".join(output)
        logger.info(
            f"Kong configuration generated: {len(result)} bytes, {len(config.services)} services"
        )
        return result

    def _generate_kong_logging_plugins(self, logging_config) -> list:
        """Generate Kong logging plugins.

        Args:
            logging_config: LoggingConfig object

        Returns:
            List of plugin dictionaries
        """
        plugins = []

        if logging_config.enabled:
            # file-log plugin
            log_config = {"path": logging_config.access_log_path}

            if logging_config.format == "json":
                log_config["format"] = "json"

            # Custom fields
            if logging_config.custom_fields:
                log_config["custom_fields_by_lua"] = logging_config.custom_fields

            plugins.append({"name": "file-log", "config": log_config})

        return plugins

    def _generate_kong_metrics_plugins(self, metrics_config) -> list:
        """Generate Kong metrics plugins.

        Args:
            metrics_config: MetricsConfig object

        Returns:
            List of plugin dictionaries
        """
        plugins = []

        if metrics_config.enabled and metrics_config.exporter in ("prometheus", "both"):
            # Prometheus plugin
            plugins.append({"name": "prometheus", "config": {}})
            logger.info(f"Prometheus metrics enabled at http://<kong_host>:8001/metrics")

        return plugins

    def _generate_kong_upstream(self, service, output: list):
        """Generate Kong upstream configuration with health checks and load balancing.

        Creates Kong upstream configuration supporting:
        - Multiple targets with weights
        - Active health checks (HTTP/HTTPS probing)
        - Passive health checks (circuit breaker)
        - Load balancing algorithms

        Args:
            service: Service object with upstream configuration
            output: Output list to append YAML lines to

        Example:
            >>> output = []
            >>> provider._generate_kong_upstream(service, output)
            >>> "healthchecks:" in output
            True
        """
        upstream_name = f"{service.name}_upstream"
        output.append(f"- name: {upstream_name}")

        # Configure load balancing algorithm
        if service.upstream.load_balancer:
            algorithm = service.upstream.load_balancer.algorithm
            # Kong algorithms: round-robin, least-connections, consistent-hashing (ip_hash)
            kong_algo_map = {
                "round_robin": "round-robin",
                "least_conn": "least-connections",
                "ip_hash": "consistent-hashing",
                "weighted": "round-robin",  # Weighted uses round-robin with target weights
            }
            output.append(f"  algorithm: {kong_algo_map.get(algorithm, 'round-robin')}")

            # For consistent hashing (IP hash), configure hash_on
            if algorithm == "ip_hash":
                output.append("  hash_on: consumer")
                output.append("  hash_fallback: ip")
        else:
            output.append("  algorithm: round-robin")

        # Configure health checks
        if service.upstream.health_check:
            hc = service.upstream.health_check
            output.append("  healthchecks:")

            # Active health checks
            if hc.active and hc.active.enabled:
                active = hc.active
                output.append("    active:")
                output.append("      type: http")
                output.append(f"      http_path: {active.http_path}")
                output.append("      timeout: " + str(self._parse_kong_duration(active.timeout)))
                output.append("      concurrency: 10")
                output.append("      healthy:")
                output.append(f"        interval: {self._parse_kong_duration(active.interval)}")
                output.append(f"        successes: {active.healthy_threshold}")
                output.append(f"        http_statuses: {active.healthy_status_codes}")
                output.append("      unhealthy:")
                output.append(f"        interval: {self._parse_kong_duration(active.interval)}")
                output.append(f"        http_failures: {active.unhealthy_threshold}")
                output.append("        timeouts: 3")
                output.append("        http_statuses: [429, 500, 503]")

            # Passive health checks
            if hc.passive and hc.passive.enabled:
                passive = hc.passive
                output.append("    passive:")
                output.append("      type: http")
                output.append("      healthy:")
                output.append("        successes: 1")
                output.append(
                    "        http_statuses: [200, 201, 202, 204, 301, 302, 303, 304, 307, 308]"
                )
                output.append("      unhealthy:")
                output.append(f"        http_failures: {passive.max_failures}")
                output.append(f"        http_statuses: {passive.unhealthy_status_codes}")
                output.append("        tcp_failures: 0")
                output.append("        timeouts: 0")

        # Configure targets
        output.append("  targets:")
        if service.upstream.targets:
            # Multiple targets mode
            for target in service.upstream.targets:
                output.append(f"  - target: {target.host}:{target.port}")
                output.append(f"    weight: {target.weight * 100}")  # Kong uses 0-1000 scale
        else:
            # Simple mode (single host/port)
            output.append(f"  - target: {service.upstream.host}:{service.upstream.port}")
            output.append("    weight: 100")

    def _parse_kong_duration(self, duration: str) -> int:
        """Parse duration string to seconds for Kong configuration.

        Args:
            duration: Duration string (e.g., "10s", "1m")

        Returns:
            int: Duration in seconds

        Example:
            >>> provider._parse_kong_duration("10s")
            10
        """
        duration = duration.strip()
        if duration.endswith("s"):
            return int(duration[:-1])
        elif duration.endswith("m"):
            return int(duration[:-1]) * 60
        elif duration.endswith("h"):
            return int(duration[:-1]) * 3600
        else:
            return int(duration)

    def deploy(
        self, config: Config, output_file: Optional[str] = None, admin_url: Optional[str] = None
    ) -> bool:
        """Deploy Kong declarative configuration.

        Deploys configuration via Kong Admin API (DB-less mode) or file-based.

        Deployment Methods:
            1. Admin API (recommended): POST config to Kong Admin API
            2. File-based: Write config to file for Kong to load

        Args:
            config: Configuration to deploy
            output_file: Path to write config file (default: kong.yaml)
            admin_url: Kong Admin API URL (default: http://localhost:8001)

        Returns:
            True if deployment successful

        Raises:
            IOError: If file write fails
            requests.RequestException: If Admin API call fails

        Example:
            >>> provider = KongProvider()
            >>> config = Config.from_yaml("config.yaml")
            >>> # File-based deployment
            >>> provider.deploy(config, output_file="/etc/kong/kong.yaml")
            True
            >>> # Via Admin API
            >>> provider.deploy(config, admin_url="http://kong:8001")
            True
        """
        logger.info(f"Deploying Kong configuration to file: {output_file or 'kong.yaml'}")
        # Generate configuration
        generated_config = self.generate(config)

        # Determine output file
        if output_file is None:
            output_file = "kong.yaml"

        # Write configuration to file
        try:
            # Create directory if it doesn't exist
            os.makedirs(os.path.dirname(output_file) or ".", exist_ok=True)

            with open(output_file, "w") as f:
                f.write(generated_config)

            logger.info(f"Kong configuration successfully written to {output_file}")
            print(f"✓ Kong configuration written to {output_file}")
        except IOError as e:
            logger.error(f"Failed to write Kong config file to {output_file}: {e}")
            print(f"✗ Failed to write config file: {e}")
            return False

        # Optionally deploy via Admin API
        if admin_url:
            admin_url = admin_url.rstrip("/")
            logger.debug(f"Checking Kong Admin API at {admin_url}")
            try:
                # Check if Kong Admin API is reachable
                response = requests.get(f"{admin_url}/status", timeout=5)

                if response.status_code == 200:
                    logger.info(f"Kong Admin API is reachable at {admin_url}")
                    print(f"✓ Kong Admin API is reachable at {admin_url}")

                    # Upload declarative config
                    with open(output_file, "rb") as f:
                        config_data = f.read()

                    logger.debug(f"Uploading configuration to Kong Admin API")
                    upload_response = requests.post(
                        f"{admin_url}/config",
                        data=config_data,
                        headers={"Content-Type": "application/x-yaml"},
                        timeout=10,
                    )

                    if upload_response.status_code in (200, 201):
                        logger.info(f"Configuration deployed successfully to Kong")
                        print(f"✓ Configuration deployed successfully to Kong")
                        return True
                    else:
                        logger.error(
                            f"Failed to deploy config to Kong: {upload_response.status_code}"
                        )
                        print(f"✗ Failed to deploy config: {upload_response.status_code}")
                        print(f"  Response: {upload_response.text}")
                        return False
                else:
                    logger.warning(f"Kong Admin API returned status {response.status_code}")
                    print(f"⚠ Kong Admin API returned status {response.status_code}")

            except requests.RequestException as e:
                logger.warning(f"Could not reach Kong Admin API at {admin_url}: {e}")
                print(f"⚠ Could not reach Kong Admin API: {e}")
                print(
                    f"  Config written to {output_file}, use: kong config db_import {output_file}"
                )

        logger.info("Kong deployment completed successfully")
        return True

    def parse(self, provider_config: str) -> Config:
        """Parse Kong declarative config to GAL format.

        Args:
            provider_config: Kong YAML/JSON configuration string

        Returns:
            Config: GAL configuration object

        Raises:
            ValueError: If config is invalid or cannot be parsed
        """
        logger.info("Parsing Kong configuration to GAL format")

        # Try YAML first, then JSON
        try:
            kong_config = yaml.safe_load(provider_config)
        except yaml.YAMLError:
            try:
                kong_config = json.loads(provider_config)
            except json.JSONDecodeError as e:
                raise ValueError(f"Invalid YAML/JSON: {e}")

        self._import_warnings = []

        # Create default global config
        global_config = GlobalConfig(host="0.0.0.0", port=8000, timeout="60s")  # Kong proxy port

        return Config(
            version="1.0",
            provider="kong",
            global_config=global_config,
            services=self._parse_services(kong_config),
        )

    def _parse_services(self, kong_config: dict) -> List[Service]:
        """Parse Kong services to GAL services."""
        services = []

        kong_services = kong_config.get("services", [])
        kong_routes = kong_config.get("routes", [])
        kong_plugins = kong_config.get("plugins", [])
        kong_upstreams = kong_config.get("upstreams", [])
        kong_targets = kong_config.get("targets", [])

        for kong_service in kong_services:
            service = self._parse_service(
                kong_service, kong_routes, kong_plugins, kong_upstreams, kong_targets
            )
            if service:
                services.append(service)

        return services

    def _parse_service(
        self,
        kong_service: dict,
        kong_routes: list,
        kong_plugins: list,
        kong_upstreams: list,
        kong_targets: list,
    ) -> Optional[Service]:
        """Convert Kong service to GAL service."""
        name = kong_service.get("name")
        if not name:
            return None

        # Parse upstream
        upstream = self._parse_upstream(kong_service, kong_upstreams, kong_targets)

        # Parse routes for this service
        routes = []
        for kong_route in kong_routes:
            # Check if route references this service
            route_service = kong_route.get("service")
            if isinstance(route_service, dict):
                route_service_name = route_service.get("name")
            elif isinstance(route_service, str):
                route_service_name = route_service
            else:
                route_service_name = None

            if route_service_name == name:
                route = self._parse_route(kong_route, kong_plugins)
                if route:
                    routes.append(route)

        return Service(
            name=name,
            type="rest",  # Kong services are typically REST
            protocol="http",
            upstream=upstream,
            routes=routes,
        )

    def _parse_upstream(
        self, kong_service: dict, kong_upstreams: list, kong_targets: list
    ) -> Optional[Upstream]:
        """Parse Kong upstream to GAL upstream."""
        # Check if service has url or host
        url = kong_service.get("url")
        host = kong_service.get("host")
        port = kong_service.get("port", 80)

        # Determine upstream name
        upstream_name = None
        if url:
            # Parse URL: http://host:port
            if "://" in url:
                protocol_and_rest = url.split("://", 1)
                rest = protocol_and_rest[1]
                if ":" in rest:
                    host, port_str = rest.rsplit(":", 1)
                    try:
                        port = int(port_str)
                    except ValueError:
                        port = 80
                else:
                    host = rest
                    port = 80
            else:
                host = url

        upstream_name = host

        # Find matching upstream
        kong_upstream = None
        for upstream in kong_upstreams:
            if upstream.get("name") == upstream_name:
                kong_upstream = upstream
                break

        if kong_upstream:
            # Service uses upstream with load balancing
            targets = self._parse_targets(upstream_name, kong_targets)

            # Parse load balancing algorithm
            algorithm = self._map_lb_algorithm(kong_upstream.get("algorithm", "round-robin"))

            # Parse health checks
            health_check = self._parse_health_check(kong_upstream)

            return Upstream(
                targets=targets,
                load_balancer=LoadBalancerConfig(algorithm=algorithm),
                health_check=health_check,
            )
        else:
            # Direct host:port without upstream
            if not host:
                return None

            return Upstream(
                targets=[UpstreamTarget(host=host, port=port)],
                load_balancer=LoadBalancerConfig(algorithm="round_robin"),
            )

    def _parse_targets(self, upstream_name: str, kong_targets: list) -> List[UpstreamTarget]:
        """Parse Kong targets for upstream."""
        targets = []

        for target in kong_targets:
            # Check upstream reference
            target_upstream = target.get("upstream")
            if isinstance(target_upstream, dict):
                target_upstream_name = target_upstream.get("name")
            elif isinstance(target_upstream, str):
                target_upstream_name = target_upstream
            else:
                continue

            if target_upstream_name != upstream_name:
                continue

            target_str = target.get("target")  # Format: "host:port"
            weight = target.get("weight", 1)

            if not target_str:
                continue

            # Parse host:port
            if ":" in target_str:
                host, port_str = target_str.rsplit(":", 1)
                try:
                    port = int(port_str)
                except ValueError:
                    port = 80
            else:
                host = target_str
                port = 80

            targets.append(UpstreamTarget(host=host, port=port, weight=weight))

        return targets

    def _map_lb_algorithm(self, kong_algorithm: str) -> str:
        """Map Kong algorithm to GAL."""
        mapping = {
            "round-robin": "round_robin",
            "least-connections": "least_conn",
            "consistent-hashing": "ip_hash",
            "latency": "least_conn",
        }
        return mapping.get(kong_algorithm, "round_robin")

    def _parse_health_check(self, kong_upstream: dict) -> Optional[HealthCheckConfig]:
        """Parse Kong health checks."""
        healthchecks = kong_upstream.get("healthchecks", {})

        active = healthchecks.get("active", {})
        passive = healthchecks.get("passive", {})

        active_hc = None
        passive_hc = None

        if active and active.get("healthy", {}).get("interval"):
            # Active health checks enabled
            healthy = active.get("healthy", {})
            unhealthy = active.get("unhealthy", {})

            http_path = active.get("http_path", "/")
            interval = f"{healthy.get('interval', 10)}s"
            timeout = f"{active.get('timeout', 5)}s"
            healthy_threshold = healthy.get("successes", 2)
            unhealthy_threshold = unhealthy.get("http_failures", 3)

            active_hc = ActiveHealthCheck(
                enabled=True,
                http_path=http_path,
                interval=interval,
                timeout=timeout,
                healthy_threshold=healthy_threshold,
                unhealthy_threshold=unhealthy_threshold,
                healthy_status_codes=[200, 302],
            )

        if passive and passive.get("healthy", {}).get("successes"):
            # Passive health checks enabled
            unhealthy = passive.get("unhealthy", {})
            max_failures = unhealthy.get("http_failures", 3)

            passive_hc = PassiveHealthCheck(enabled=True, max_failures=max_failures)

        if active_hc or passive_hc:
            return HealthCheckConfig(active=active_hc, passive=passive_hc)

        return None

    def _parse_route(self, kong_route: dict, kong_plugins: list) -> Optional[Route]:
        """Parse Kong route to GAL route."""
        # Parse paths
        paths = kong_route.get("paths", [])
        if not paths:
            return None

        path_prefix = paths[0]  # Take first path

        # Parse methods
        methods = kong_route.get("methods")

        # Parse plugins for this route
        route_name = kong_route.get("name")

        rate_limit = None
        authentication = None
        headers = None
        cors = None

        for plugin in kong_plugins:
            # Check if plugin applies to this route
            plugin_route = plugin.get("route")
            if isinstance(plugin_route, dict):
                plugin_route_name = plugin_route.get("name")
            elif isinstance(plugin_route, str):
                plugin_route_name = plugin_route
            else:
                plugin_route_name = None

            if plugin_route_name != route_name:
                continue

            plugin_name = plugin.get("name")
            plugin_config = plugin.get("config", {})

            if plugin_name == "rate-limiting":
                rate_limit = self._parse_rate_limiting_plugin(plugin_config)
            elif plugin_name == "key-auth":
                authentication = self._parse_key_auth_plugin(plugin_config)
            elif plugin_name == "basic-auth":
                authentication = self._parse_basic_auth_plugin(plugin_config)
            elif plugin_name == "jwt":
                authentication = self._parse_jwt_plugin(plugin_config)
            elif plugin_name == "request-transformer":
                headers = self._parse_request_transformer_plugin(plugin_config)
            elif plugin_name == "response-transformer":
                if headers:
                    self._enrich_response_headers(headers, plugin_config)
                else:
                    headers = self._parse_response_transformer_plugin(plugin_config)
            elif plugin_name == "cors":
                cors = self._parse_cors_plugin(plugin_config)

        return Route(
            path_prefix=path_prefix,
            methods=methods,
            rate_limit=rate_limit,
            authentication=authentication,
            headers=headers,
            cors=cors,
        )

    def _parse_rate_limiting_plugin(self, config: dict) -> RateLimitConfig:
        """Parse Kong rate-limiting plugin."""
        # Kong supports minute, hour, day, month, year
        # We'll use minute and convert to per-second
        limit_by = config.get("limit_by", "consumer")
        minute = config.get("minute")
        second = config.get("second")

        if second:
            rps = second
        elif minute:
            rps = minute // 60  # Approximation
        else:
            rps = 100  # Default

        key_type = "ip_address" if limit_by == "ip" else "header"
        key_header = "X-Consumer-ID" if limit_by == "consumer" else None

        return RateLimitConfig(
            enabled=True,
            requests_per_second=rps,
            burst=rps * 2,
            key_type=key_type,
            key_header=key_header,
        )

    def _parse_key_auth_plugin(self, config: dict) -> AuthenticationConfig:
        """Parse Kong key-auth plugin."""
        return AuthenticationConfig(
            enabled=True,
            type="api_key",
            api_key=ApiKeyConfig(
                keys=[],  # Keys not imported for security
                key_name=config.get("key_names", ["apikey"])[0],
                in_location="header",
            ),
        )

    def _parse_basic_auth_plugin(self, config: dict) -> AuthenticationConfig:
        """Parse Kong basic-auth plugin."""
        # Kong stores users separately, we can't import them
        self._import_warnings.append("Basic auth users not imported - configure manually")

        return AuthenticationConfig(
            enabled=True,
            type="basic",
            basic_auth=BasicAuthConfig(users={}, realm="Protected"),  # Must be configured manually
        )

    def _parse_jwt_plugin(self, config: dict) -> AuthenticationConfig:
        """Parse Kong JWT plugin."""
        # Extract algorithm (Kong supports multiple)
        algorithm = config.get("algorithm", "HS256")
        if isinstance(algorithm, str):
            algorithms = [algorithm]
        else:
            algorithms = algorithm if algorithm else ["HS256"]

        self._import_warnings.append("JWT keys/secrets not imported - configure manually")

        return AuthenticationConfig(
            enabled=True,
            type="jwt",
            jwt=JwtConfig(
                issuer="CONFIGURE_MANUALLY",
                audience="CONFIGURE_MANUALLY",
                jwks_uri="",
                algorithms=algorithms,
                required_claims=[],
            ),
        )

    def _parse_request_transformer_plugin(self, config: dict) -> HeaderManipulation:
        """Parse Kong request-transformer plugin."""
        add = config.get("add", {}).get("headers", [])
        remove = config.get("remove", {}).get("headers", [])

        request_add = {}
        for header_value in add:
            # Format: "Header-Name:value"
            if ":" in header_value:
                key, value = header_value.split(":", 1)
                request_add[key] = value.strip()

        request_remove = remove if remove else None

        return HeaderManipulation(
            request_add=request_add if request_add else None, request_remove=request_remove
        )

    def _parse_response_transformer_plugin(self, config: dict) -> HeaderManipulation:
        """Parse Kong response-transformer plugin."""
        add = config.get("add", {}).get("headers", [])
        remove = config.get("remove", {}).get("headers", [])

        response_add = {}
        for header_value in add:
            if ":" in header_value:
                key, value = header_value.split(":", 1)
                response_add[key] = value.strip()

        response_remove = remove if remove else None

        return HeaderManipulation(
            response_add=response_add if response_add else None, response_remove=response_remove
        )

    def _enrich_response_headers(self, headers: HeaderManipulation, config: dict):
        """Add response headers to existing HeaderManipulation."""
        add = config.get("add", {}).get("headers", [])
        remove = config.get("remove", {}).get("headers", [])

        if not headers.response_add:
            headers.response_add = {}

        for header_value in add:
            if ":" in header_value:
                key, value = header_value.split(":", 1)
                headers.response_add[key] = value.strip()

        if remove and not headers.response_remove:
            headers.response_remove = remove

    def _parse_cors_plugin(self, config: dict) -> CORSPolicy:
        """Parse Kong CORS plugin."""
        origins = config.get("origins", ["*"])
        methods = config.get("methods", ["GET", "POST", "PUT", "DELETE"])
        headers = config.get("headers", [])
        credentials = config.get("credentials", False)
        max_age = config.get("max_age", 86400)

        return CORSPolicy(
            enabled=True,
            allowed_origins=origins,
            allowed_methods=methods,
            allowed_headers=headers if headers else None,
            allow_credentials=credentials,
            max_age=str(max_age),
        )

    def get_import_warnings(self) -> List[str]:
        """Return warnings from last import."""
        return getattr(self, "_import_warnings", [])
