# 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.

"""
Integration tests for TLS connectivity using testcontainers.

These tests spin up a TLS-enabled Iggy server in a Docker container
so they are fully self-contained and work in CI without a pre-running
TLS server.

Requirements:
    - Docker running locally
    - testcontainers[docker] installed (in [testing-docker] extras)
    - CA certificate available at core/certs/iggy_ca_cert.pem
    - server image built locally (or IGGY_SERVER_DOCKER_IMAGE set):
      docker build -f core/server/Dockerfile --target runtime-prebuilt \
        --build-arg PREBUILT_IGGY_SERVER=target/debug/iggy-server \
        --build-arg PREBUILT_IGGY_CLI=target/debug/iggy \
        -t iggy-server:local .
"""

import asyncio
import os

import pytest
from testcontainers.core.container import DockerContainer
from testcontainers.core.waiting_utils import wait_for_logs

from apache_iggy import Consumer, IggyClient, PollingStrategy
from apache_iggy import SendMessage as Message

from .utils import wait_for_ping, wait_for_server

# Paths resolved relative to this file → repo root
REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
CERTS_DIR = os.path.join(REPO_ROOT, "core", "certs")
CA_FILE = os.path.join(CERTS_DIR, "iggy_ca_cert.pem")

IGGY_IMAGE = os.environ.get("IGGY_SERVER_DOCKER_IMAGE", "iggy-server:local")
CONTAINER_TCP_PORT = 8090


@pytest.fixture(scope="module")
def tls_container():
    """Start a TLS-enabled Iggy server in Docker."""
    container = (
        DockerContainer(IGGY_IMAGE)
        .with_exposed_ports(CONTAINER_TCP_PORT)
        .with_env("IGGY_ROOT_USERNAME", "iggy")
        .with_env("IGGY_ROOT_PASSWORD", "iggy")
        .with_env("IGGY_TCP_TLS_ENABLED", "true")
        .with_env("IGGY_TCP_TLS_CERT_FILE", "/app/certs/iggy_cert.pem")
        .with_env("IGGY_TCP_TLS_KEY_FILE", "/app/certs/iggy_key.pem")
        .with_env("IGGY_TCP_ADDRESS", f"0.0.0.0:{CONTAINER_TCP_PORT}")
        .with_env("IGGY_NODE_ADVERTISED_ADDRESS", "127.0.0.1")
        .with_volume_mapping(CERTS_DIR, "/app/certs", "ro")
        .with_kwargs(privileged=True)
    )
    container.start()
    # Wait for the server to be ready inside the container
    wait_for_logs(container, "server running", timeout=60)
    yield container
    container.stop()


@pytest.fixture(scope="module")
async def tls_client(tls_container) -> IggyClient:
    """Create an authenticated client connected to the TLS container."""
    host = "localhost"
    port = tls_container.get_exposed_port(CONTAINER_TCP_PORT)

    wait_for_server(host, int(port))

    conn_str = (
        f"iggy+tcp://iggy:iggy@{host}:{port}"
        f"?tls=true&tls_domain={host}&tls_ca_file={CA_FILE}"
    )
    client = IggyClient.from_connection_string(conn_str)
    await client.connect()
    await wait_for_ping(client)
    return client


@pytest.mark.integration
class TestTlsConnectivity:
    """Test TLS connection establishment and basic operations."""

    @pytest.mark.asyncio
    async def test_ping_over_tls(self, tls_client: IggyClient):
        """Test that the server responds to ping over a TLS connection."""
        await tls_client.ping()

    @pytest.mark.asyncio
    async def test_client_not_none(self, tls_client: IggyClient):
        """Test that the TLS client fixture is properly initialized."""
        assert tls_client is not None

    @pytest.mark.asyncio
    async def test_create_stream_over_tls(self, tls_client: IggyClient, unique_name):
        """Test creating and getting a stream over TLS."""
        stream_name = unique_name()
        await tls_client.create_stream(stream_name)
        stream = await tls_client.get_stream(stream_name)
        assert stream is not None

    @pytest.mark.asyncio
    async def test_produce_and_consume_over_tls(
        self, tls_client: IggyClient, unique_name
    ):
        """Test producing and consuming messages over TLS."""
        stream_name = unique_name()
        topic_name = unique_name()
        partition_id = 0

        # Create stream and topic
        await tls_client.create_stream(stream_name)
        await tls_client.create_topic(stream_name, topic_name, partitions_count=1)

        # Produce messages
        test_messages = [f"tls-message-{i}" for i in range(3)]
        messages = [Message(msg) for msg in test_messages]
        await tls_client.send_messages(
            stream=stream_name,
            topic=topic_name,
            partitioning=partition_id,
            messages=messages,
        )

        # Consume messages
        polled = await tls_client.poll_messages(
            stream=stream_name,
            topic=topic_name,
            consumer=Consumer.Single(1),
            partition_id=partition_id,
            polling_strategy=PollingStrategy.First(),
            count=10,
            auto_commit=True,
        )
        assert len(polled) >= len(test_messages)

        # Verify message payloads
        for i, expected_msg in enumerate(test_messages):
            if i < len(polled):
                assert polled[i].payload().decode("utf-8") == expected_msg


@pytest.mark.integration
class TestTlsConnectionString:
    """Test TLS connection string variations."""

    @pytest.mark.asyncio
    async def test_connection_string_with_tls_params(self, tls_container):
        """Test creating a client from a connection string with TLS parameters."""
        host = "localhost"
        port = tls_container.get_exposed_port(CONTAINER_TCP_PORT)

        wait_for_server(host, int(port))

        conn_str = (
            f"iggy+tcp://iggy:iggy@{host}:{port}"
            f"?tls=true&tls_domain={host}&tls_ca_file={CA_FILE}"
        )
        client = IggyClient.from_connection_string(conn_str)
        await client.connect()
        await wait_for_ping(client)
        await client.ping()

    @pytest.mark.asyncio
    @pytest.mark.timeout(10)
    async def test_connect_without_tls_should_fail(self, tls_container):
        """Test that connecting without TLS to a TLS-enabled server fails."""
        host = "localhost"
        port = tls_container.get_exposed_port(CONTAINER_TCP_PORT)

        wait_for_server(host, int(port))

        # Use connection string without TLS params to a TLS-enabled server
        # The SDK retries internally, so we use a timeout to detect failure
        conn_str = f"iggy+tcp://iggy:iggy@{host}:{port}"
        client = IggyClient.from_connection_string(conn_str)

        with pytest.raises(Exception):
            await asyncio.wait_for(client.connect(), timeout=5)
