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

import datetime

import pytest

from apache_iggy import CacheMetricsKey, GlobalPermissions, IggyClient, Permissions
from apache_iggy import SendMessage as Message

from .utils import (
    get_server_config,
    login_fresh_client,
    unique_credentials,
    wait_for_server,
)

# Fields that describe the server process itself and must not change between
# two calls within one server run.
PROCESS_IDENTITY_FIELDS = (
    "process_id",
    "start_time",
    "hostname",
    "os_name",
    "os_version",
    "kernel_version",
    "iggy_server_version",
    "iggy_server_semver",
)


class TestStats:
    """Test server statistics retrieval."""

    @pytest.mark.asyncio
    async def test_get_stats(self, iggy_client: IggyClient, unique_name):
        """Sending messages moves the server counts reported by get_stats."""
        stats_before = await iggy_client.get_stats()

        stream_name = unique_name()
        topic_name = unique_name()
        await iggy_client.create_stream(stream_name)
        await iggy_client.create_topic(
            stream=stream_name, name=topic_name, partitions_count=1
        )
        await iggy_client.send_messages(
            stream=stream_name,
            topic=topic_name,
            partitioning=0,
            messages=[Message(f"stats message {i}") for i in range(3)],
        )

        stats = await iggy_client.get_stats()

        # `>=` rather than exact equality: the counters are server-global, so
        # concurrently running tests (e.g. under pytest-xdist) may bump them too.
        assert stats.streams_count >= stats_before.streams_count + 1
        assert stats.topics_count >= stats_before.topics_count + 1
        assert stats.partitions_count >= stats_before.partitions_count + 1
        assert stats.messages_count >= stats_before.messages_count + 3
        assert stats.messages_size_bytes > stats_before.messages_size_bytes
        assert stats.clients_count >= 1

        assert stats.iggy_server_version
        assert stats.hostname
        assert stats.os_name
        assert stats.os_version
        assert stats.kernel_version
        assert stats.process_id > 0
        # sysinfo cannot enumerate a process's threads on macOS, so a server
        # running there reports 0.
        if stats.os_name != "Darwin":
            assert stats.threads_count > 0
        assert stats.start_time > 0
        assert stats.total_memory > 0
        assert stats.available_memory <= stats.total_memory
        assert stats.total_disk_space > 0
        assert stats.free_disk_space <= stats.total_disk_space

        assert isinstance(stats.run_time, datetime.timedelta)
        assert stats.run_time >= stats_before.run_time
        for field in PROCESS_IDENTITY_FIELDS:
            assert getattr(stats, field) == getattr(stats_before, field)

        assert f"streams_count={stats.streams_count}" in repr(stats)
        assert stats.hostname in repr(stats)

    @pytest.mark.asyncio
    async def test_get_stats_reflects_topology(
        self, iggy_client: IggyClient, unique_name
    ):
        """Streams, topics, partitions, consumer groups and a second client show
        up in the counters, and deleting the streams brings them back down."""
        stats_before = await iggy_client.get_stats()

        streams = [unique_name() for _ in range(2)]
        topics_per_stream = 2
        partitions_per_topic = 3
        topics = []
        for stream_name in streams:
            await iggy_client.create_stream(stream_name)
            for _ in range(topics_per_stream):
                topic_name = unique_name()
                await iggy_client.create_topic(
                    stream=stream_name,
                    name=topic_name,
                    partitions_count=partitions_per_topic,
                )
                await iggy_client.create_consumer_group(
                    stream_name, topic_name, unique_name()
                )
                topics.append((stream_name, topic_name))
        # Bound only to keep a second connection open until the test ends.
        _second_client = await login_fresh_client("iggy", "iggy")

        topics_created = len(topics)
        partitions_created = topics_created * partitions_per_topic

        stats = await iggy_client.get_stats()

        assert stats.streams_count >= stats_before.streams_count + len(streams)
        assert stats.topics_count >= stats_before.topics_count + topics_created
        assert (
            stats.partitions_count >= stats_before.partitions_count + partitions_created
        )
        # Every new partition opens with one segment.
        assert stats.segments_count >= stats_before.segments_count + partitions_created
        assert (
            stats.consumer_groups_count
            >= stats_before.consumer_groups_count + topics_created
        )
        # Both `iggy_client` and `_second_client` are connected at this point, so
        # the cross-shard total covers them regardless of what else the server
        # reaped in between.
        assert stats.clients_count >= 2

        # The SDK has no delete_stream, so the streams stay behind and only the
        # topic-level counters are expected to drop. The baseline is re-read
        # right before the deletes to keep the window in which a concurrent
        # test can bump the server-global counters as small as possible.
        stats_before_delete = await iggy_client.get_stats()
        for stream_name, topic_name in topics:
            await iggy_client.delete_topic(stream_name, topic_name)

        stats_after = await iggy_client.get_stats()

        assert (
            stats_after.topics_count
            <= stats_before_delete.topics_count - topics_created
        )
        assert (
            stats_after.partitions_count
            <= stats_before_delete.partitions_count - partitions_created
        )
        assert (
            stats_after.segments_count
            <= stats_before_delete.segments_count - partitions_created
        )
        assert (
            stats_after.consumer_groups_count
            <= stats_before_delete.consumer_groups_count - topics_created
        )

    @pytest.mark.asyncio
    async def test_get_stats_cache_metrics_dict(self, iggy_client: IggyClient):
        """cache_metrics is a dict the server currently leaves empty."""
        stats = await iggy_client.get_stats()

        assert stats.cache_metrics == {}

    @pytest.mark.unit
    def test_cache_metrics_key_is_constructible_and_hashable(self):
        """A key built in Python can address a cache_metrics dict entry."""
        key = CacheMetricsKey(stream_id=1, topic_id=2, partition_id=3)

        assert key.stream_id == 1
        assert key.topic_id == 2
        assert key.partition_id == 3
        assert repr(key) == "CacheMetricsKey(stream_id=1, topic_id=2, partition_id=3)"

        equal_key = CacheMetricsKey(stream_id=1, topic_id=2, partition_id=3)
        other_key = CacheMetricsKey(stream_id=1, topic_id=2, partition_id=4)
        assert key == equal_key
        assert key != other_key
        assert hash(key) == hash(equal_key)

        # An equal key constructed independently hits the same dict slot.
        metrics_by_key = {key: "metrics"}
        assert metrics_by_key[equal_key] == "metrics"
        assert other_key not in metrics_by_key

    @pytest.mark.asyncio
    async def test_get_stats_requires_connection_and_auth(self):
        """get_stats fails before connecting, before login, and after logout."""
        host, port = get_server_config()
        wait_for_server(host, port)

        client = IggyClient(f"{host}:{port}")
        with pytest.raises(RuntimeError, match="Not connected"):
            await client.get_stats()

        await client.connect()
        with pytest.raises(RuntimeError, match="Unauthenticated"):
            await client.get_stats()

        await client.login_user("iggy", "iggy")
        await client.get_stats()

        await client.logout_user()
        with pytest.raises(RuntimeError, match="Unauthenticated"):
            await client.get_stats()

    @pytest.mark.asyncio
    @pytest.mark.parametrize("flag", ["read_servers", "manage_servers"])
    async def test_get_stats_requires_server_permission(
        self, iggy_client: IggyClient, unique_name, flag
    ):
        """A user without read_servers or manage_servers is denied; either grants."""
        username, password = unique_credentials(unique_name)
        created = await iggy_client.create_user(username, password)

        try:
            denied_client = await login_fresh_client(username, password)
            with pytest.raises(RuntimeError, match="Unauthorized"):
                await denied_client.get_stats()

            await iggy_client.update_permissions(
                created.id,
                Permissions(global_permissions=GlobalPermissions(**{flag: True})),
            )

            granted_client = await login_fresh_client(username, password)
            stats = await granted_client.get_stats()
            assert stats.process_id > 0
        finally:
            await iggy_client.delete_user(created.id)
