"""Tests for default deployment files shipped with entr-adapter-core."""

import pytest
from importlib.resources import files
from pathlib import Path


# All default files that must ship with the package (AC1)
EXPECTED_DEFAULT_FILES = [
    "Dockerfile",
    "nginx.conf",
    "docker-compose.dev.yml",
    "docker-compose.prod.yml",
    "fluent-bit.conf",
    "prefix.lua",
]


@pytest.fixture
def defaults_path():
    """Resolve the defaults directory via importlib.resources."""
    return files("entr_adapter_core") / "defaults"


class TestDefaultFilesExist:
    """AC1: All required default deployment files exist in the package."""

    @pytest.mark.parametrize("filename", EXPECTED_DEFAULT_FILES)
    def test_default_file_exists(self, defaults_path, filename):
        path = defaults_path / filename
        assert path.is_file(), f"Missing default file: {filename}"

    @pytest.mark.parametrize("filename", EXPECTED_DEFAULT_FILES)
    def test_default_file_not_empty(self, defaults_path, filename):
        path = defaults_path / filename
        content = path.read_text()
        assert len(content.strip()) > 0, f"Default file is empty: {filename}"


class TestDockerfile:
    """AC2: Dockerfile uses uv-based Python 3.12 build, port 8096."""

    @pytest.fixture
    def dockerfile_content(self, defaults_path):
        return (defaults_path / "Dockerfile").read_text()

    def test_base_image(self, dockerfile_content):
        assert "ghcr.io/astral-sh/uv:python3.12-bookworm-slim" in dockerfile_content

    def test_uv_sync(self, dockerfile_content):
        assert "uv sync" in dockerfile_content

    def test_exposes_port_8096(self, dockerfile_content):
        assert "EXPOSE 8096" in dockerfile_content

    def test_runs_uvicorn(self, dockerfile_content):
        assert "uvicorn" in dockerfile_content
        assert "src.main:app" in dockerfile_content

    def test_port_8096_in_cmd(self, dockerfile_content):
        assert "8096" in dockerfile_content

    def test_bytecode_compilation(self, dockerfile_content):
        assert "UV_COMPILE_BYTECODE=1" in dockerfile_content

    def test_copy_link_mode(self, dockerfile_content):
        assert "UV_LINK_MODE=copy" in dockerfile_content

    def test_no_tenant_specific_values(self, dockerfile_content):
        # Should not contain any tenant-specific hardcoded values
        assert "MessageBird" not in dockerfile_content
        assert "Nest" not in dockerfile_content


class TestNginxConf:
    """AC3: nginx.conf routes Core traffic (nextapp + backend) with SSE support."""

    @pytest.fixture
    def nginx_content(self, defaults_path):
        return (defaults_path / "nginx.conf").read_text()

    def test_upstream_definitions(self, nginx_content):
        # Production nginx routes to Core services (nextapp + backend),
        # not directly to the adapter (adapter is on internal network only)
        assert "nextjs_upstream" in nginx_content
        assert "backend_upstream" in nginx_content

    def test_listen_80(self, nginx_content):
        assert "listen 80 default_server" in nginx_content

    def test_server_tokens_off(self, nginx_content):
        assert "server_tokens off" in nginx_content

    def test_gzip_enabled(self, nginx_content):
        assert "gzip on" in nginx_content

    def test_proxy_headers(self, nginx_content):
        assert "X-Real-IP" in nginx_content
        assert "X-Forwarded-For" in nginx_content
        assert "X-Forwarded-Proto" in nginx_content

    def test_sse_support(self, nginx_content):
        assert "proxy_buffering off" in nginx_content
        assert "proxy_cache off" in nginx_content
        assert "86400s" in nginx_content

    def test_client_max_body_size(self, nginx_content):
        assert "client_max_body_size 50M" in nginx_content

    def test_proxy_http_version(self, nginx_content):
        assert "proxy_http_version 1.1" in nginx_content


class TestComposeMapStyle:
    """AC6: All compose files use map-style environment variables."""

    @pytest.fixture
    def compose_files(self, defaults_path):
        return {
            name: (defaults_path / name).read_text()
            for name in EXPECTED_DEFAULT_FILES
            if name.startswith("docker-compose")
        }

    def test_no_list_style_env_vars(self, compose_files):
        import re
        pattern = re.compile(r"^\s*-\s+[A-Z_]+=", re.MULTILINE)
        for name, content in compose_files.items():
            matches = pattern.findall(content)
            assert not matches, (
                f"{name} contains list-style env vars: {matches}"
            )


class TestComposeProd:
    """AC4: docker-compose.prod.yml uses variable substitution."""

    @pytest.fixture
    def prod_content(self, defaults_path):
        return (defaults_path / "docker-compose.prod.yml").read_text()

    def test_docker_user_variable(self, prod_content):
        assert "${DOCKER_USER}" in prod_content

    def test_tenant_slug_variable(self, prod_content):
        assert "${TENANT_SLUG}" in prod_content

    def test_adapter_tag_variable(self, prod_content):
        # Uses default syntax: ${ADAPTER_TAG:-latest}
        assert "ADAPTER_TAG" in prod_content

    def test_core_tag_variable(self, prod_content):
        # Uses default syntax: ${CORE_TAG:-latest}
        assert "CORE_TAG" in prod_content

    def test_restart_policy(self, prod_content):
        assert "restart: always" in prod_content

    def test_healthcheck(self, prod_content):
        assert "healthcheck" in prod_content


class TestComposeDev:
    """AC5: docker-compose.dev.yml orchestrates Core + adapter with live reload."""

    @pytest.fixture
    def dev_content(self, defaults_path):
        return (defaults_path / "docker-compose.dev.yml").read_text()

    def test_source_mount_for_live_reload(self, dev_content):
        assert "./src:/app/src" in dev_content

    def test_reload_flag(self, dev_content):
        assert "--reload" in dev_content

    def test_core_services_present(self, dev_content):
        assert "nextapp" in dev_content
        assert "backend" in dev_content

    def test_references_entr_core(self, dev_content):
        assert "Entr-Core" in dev_content


class TestFluentBitConf:
    """AC1: fluent-bit.conf configures log forwarding to CloudWatch."""

    @pytest.fixture
    def fluentbit_content(self, defaults_path):
        return (defaults_path / "fluent-bit.conf").read_text()

    def test_cloudwatch_output(self, fluentbit_content):
        assert "cloudwatch_logs" in fluentbit_content

    def test_tenant_slug_in_log_group(self, fluentbit_content):
        assert "${TENANT_SLUG}" in fluentbit_content

    def test_forward_input(self, fluentbit_content):
        # Uses fluentd forward input (receives from Docker logging driver)
        assert "forward" in fluentbit_content
        assert "24224" in fluentbit_content


class TestCrossPlatform:
    """AC8: Files work on both Linux and macOS."""

    @pytest.mark.parametrize("filename", EXPECTED_DEFAULT_FILES)
    def test_lf_line_endings(self, defaults_path, filename):
        content = (defaults_path / filename).read_bytes()
        assert b"\r\n" not in content, f"{filename} has Windows-style line endings"

    def test_no_backslash_paths_in_compose(self, defaults_path):
        for name in EXPECTED_DEFAULT_FILES:
            if name.startswith("docker-compose"):
                content = (defaults_path / name).read_text()
                # Check volume mounts don't use backslashes
                for line in content.splitlines():
                    if "volumes:" not in line and ":" in line and "\\" in line:
                        pytest.fail(f"{name} contains backslash path: {line}")
