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

from typing import Any

import pytest

from apache_iggy import (
    GlobalPermissions,
    IggyClient,
    Permissions,
    StreamPermissions,
    TopicPermissions,
)

from .utils import (
    MAX_PASSWORD_BYTES,
    MAX_USERNAME_BYTES,
    MIN_PASSWORD_BYTES,
    get_server_config,
    login_fresh_client,
    unique_credentials,
    wait_for_ping,
)

GLOBAL_PERMISSION_FLAGS = [
    "manage_servers",
    "read_servers",
    "manage_users",
    "read_users",
    "manage_streams",
    "read_streams",
    "manage_topics",
    "read_topics",
    "poll_messages",
    "send_messages",
]

STREAM_PERMISSION_FLAGS = [
    "manage_stream",
    "read_stream",
    "manage_topics",
    "read_topics",
    "poll_messages",
    "send_messages",
]

TOPIC_PERMISSION_FLAGS = [
    "manage_topic",
    "read_topic",
    "poll_messages",
    "send_messages",
]


class TestPermissionsModel:
    """Test constructing the Permissions classes without a server."""

    def test_default_permissions_deny_everything(self):
        """Test Permissions() has every global flag off and no streams."""
        permissions = Permissions()

        assert permissions.streams is None
        global_permissions = permissions.global_permissions
        assert global_permissions.manage_servers is False
        assert global_permissions.read_servers is False
        assert global_permissions.manage_users is False
        assert global_permissions.read_users is False
        assert global_permissions.manage_streams is False
        assert global_permissions.read_streams is False
        assert global_permissions.manage_topics is False
        assert global_permissions.read_topics is False
        assert global_permissions.poll_messages is False
        assert global_permissions.send_messages is False

    @pytest.mark.parametrize("flag", GLOBAL_PERMISSION_FLAGS)
    def test_each_global_permission_flag_round_trips_alone(self, flag):
        """Test setting one flag flips only that flag."""
        global_permissions = GlobalPermissions(**{flag: True})

        for name in GLOBAL_PERMISSION_FLAGS:
            assert getattr(global_permissions, name) is (name == flag)

    @pytest.mark.parametrize("flag", STREAM_PERMISSION_FLAGS)
    def test_each_stream_permission_flag_round_trips_alone(self, flag):
        """Test setting one flag flips only that flag."""
        flags: dict[str, Any] = {flag: True}
        stream_permissions = StreamPermissions(**flags)

        for name in STREAM_PERMISSION_FLAGS:
            assert getattr(stream_permissions, name) is (name == flag)

    @pytest.mark.parametrize("flag", TOPIC_PERMISSION_FLAGS)
    def test_each_topic_permission_flag_round_trips_alone(self, flag):
        """Test setting one flag flips only that flag."""
        topic_permissions = TopicPermissions(**{flag: True})

        for name in TOPIC_PERMISSION_FLAGS:
            assert getattr(topic_permissions, name) is (name == flag)

    def test_nested_stream_and_topic_permissions_are_preserved(self):
        """Test stream and topic permission dicts survive construction."""
        permissions = Permissions(
            global_permissions=GlobalPermissions(read_servers=True),
            streams={
                1: StreamPermissions(
                    read_stream=True,
                    topics={7: TopicPermissions(poll_messages=True)},
                ),
                42: StreamPermissions(manage_stream=True),
            },
        )

        streams = permissions.streams
        assert streams is not None
        assert set(streams) == {1, 42}
        assert streams[1].read_stream is True
        assert streams[1].manage_stream is False
        topics = streams[1].topics
        assert topics is not None
        assert set(topics) == {7}
        assert topics[7].poll_messages is True
        assert topics[7].manage_topic is False
        assert streams[42].manage_stream is True
        assert streams[42].topics is None

    def test_empty_permission_dicts_normalize_to_none(self):
        """Test empty stream and topic dicts are equivalent to None."""
        assert Permissions(streams={}).streams is None
        assert Permissions(streams={}) == Permissions()
        assert StreamPermissions(topics={}).topics is None
        assert StreamPermissions(topics={}) == StreamPermissions()

    def test_stream_id_above_u32_is_rejected(self):
        """Test dict keys outside the u32 wire range fail at construction."""
        with pytest.raises(OverflowError):
            Permissions(streams={2**32: StreamPermissions(read_stream=True)})
        with pytest.raises(OverflowError):
            StreamPermissions(topics={2**32: TopicPermissions(read_topic=True)})

    def test_permissions_equality(self):
        """Test structurally identical Permissions compare equal."""
        first = Permissions(
            global_permissions=GlobalPermissions(read_streams=True),
            streams={3: StreamPermissions(poll_messages=True)},
        )
        second = Permissions(
            global_permissions=GlobalPermissions(read_streams=True),
            streams={3: StreamPermissions(poll_messages=True)},
        )
        different = Permissions(
            global_permissions=GlobalPermissions(manage_streams=True)
        )

        assert first == second
        assert first != different


class TestCreateUserWithPermissions:
    """Test create_user with the permissions argument."""

    @pytest.mark.asyncio
    async def test_create_user_with_global_permissions_round_trips(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test global permissions set at creation come back from get_user."""
        username, password = unique_credentials(unique_name)
        permissions = Permissions(
            global_permissions=GlobalPermissions(read_users=True, read_streams=True),
            streams={},
        )

        created = await iggy_client.create_user(
            username, password, permissions=permissions
        )
        assert created.permissions == permissions

        fetched = await iggy_client.get_user(created.id)
        assert fetched is not None
        fetched_permissions = fetched.permissions
        assert fetched_permissions is not None
        assert fetched_permissions == permissions
        assert fetched_permissions.streams is None

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_create_user_with_nested_permissions_round_trips(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test per-stream and per-topic permissions survive the round trip."""
        username, password = unique_credentials(unique_name)
        stream_name = unique_name(prefix="perm-stream-")
        await iggy_client.create_stream(stream_name)
        stream = await iggy_client.get_stream(stream_name)
        assert stream is not None
        topic_name = unique_name(prefix="perm-topic-")
        await iggy_client.create_topic(stream_name, topic_name, partitions_count=1)
        topic = await iggy_client.get_topic(stream_name, topic_name)
        assert topic is not None

        permissions = Permissions(
            streams={
                stream.id: StreamPermissions(
                    read_stream=True,
                    poll_messages=True,
                    topics={topic.id: TopicPermissions(send_messages=True)},
                )
            }
        )
        created = await iggy_client.create_user(
            username, password, permissions=permissions
        )
        assert created.permissions == permissions

        fetched = await iggy_client.get_user(created.id)
        assert fetched is not None
        fetched_permissions = fetched.permissions
        assert fetched_permissions is not None
        assert fetched_permissions == permissions
        streams = fetched_permissions.streams
        assert streams is not None
        assert streams[stream.id].read_stream is True
        topics = streams[stream.id].topics
        assert topics is not None
        assert topics[topic.id].send_messages is True

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_user_with_manage_streams_can_create_stream(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a granted global permission is enforced for the new user."""
        username, password = unique_credentials(unique_name)
        permissions = Permissions(
            global_permissions=GlobalPermissions(manage_streams=True)
        )
        created = await iggy_client.create_user(
            username, password, permissions=permissions
        )

        client = await login_fresh_client(username, password)
        stream_name = unique_name(prefix="granted-")
        await client.create_stream(stream_name)

        stream = await iggy_client.get_stream(stream_name)
        assert stream is not None

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_user_without_permissions_cannot_create_stream(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a user created without permissions is denied stream creation."""
        username, password = unique_credentials(unique_name)
        created = await iggy_client.create_user(username, password)

        client = await login_fresh_client(username, password)
        with pytest.raises(RuntimeError):
            await client.create_stream(unique_name(prefix="denied-"))

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_per_stream_permission_is_scoped_to_that_stream(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test read access to one stream does not leak to another stream."""
        readable_name = unique_name(prefix="readable-")
        hidden_name = unique_name(prefix="hidden-")
        await iggy_client.create_stream(readable_name)
        await iggy_client.create_stream(hidden_name)
        readable = await iggy_client.get_stream(readable_name)
        assert readable is not None

        username, password = unique_credentials(unique_name)
        permissions = Permissions(
            streams={readable.id: StreamPermissions(read_stream=True)}
        )
        created = await iggy_client.create_user(
            username, password, permissions=permissions
        )

        client = await login_fresh_client(username, password)
        visible = await client.get_stream(readable_name)
        assert visible is not None
        assert visible.id == readable.id
        with pytest.raises(RuntimeError):
            await client.get_stream(hidden_name)

        await iggy_client.delete_user(created.id)


class TestUpdatePermissions:
    """Test permission updates via update_permissions."""

    @pytest.mark.asyncio
    async def test_update_permissions_grants_and_round_trips(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test permissions granted after creation come back from get_user."""
        username, password = unique_credentials(unique_name)
        created = await iggy_client.create_user(username, password)
        assert created.permissions is None

        permissions = Permissions(
            global_permissions=GlobalPermissions(read_streams=True)
        )
        await iggy_client.update_permissions(created.id, permissions)

        fetched = await iggy_client.get_user(created.id)
        assert fetched is not None
        assert fetched.permissions == permissions

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_update_permissions_replaces_previous_permissions(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test update_permissions overwrites instead of merging."""
        username, password = unique_credentials(unique_name)
        initial = Permissions(
            global_permissions=GlobalPermissions(read_streams=True, read_users=True)
        )
        created = await iggy_client.create_user(username, password, permissions=initial)

        replacement = Permissions(
            global_permissions=GlobalPermissions(read_servers=True)
        )
        await iggy_client.update_permissions(created.id, replacement)

        fetched = await iggy_client.get_user(created.id)
        assert fetched is not None
        fetched_permissions = fetched.permissions
        assert fetched_permissions is not None
        assert fetched_permissions == replacement
        assert fetched_permissions.global_permissions.read_streams is False
        assert fetched_permissions.global_permissions.read_users is False

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_update_permissions_none_clears_permissions(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test update_permissions with None removes existing permissions."""
        username, password = unique_credentials(unique_name)
        permissions = Permissions(
            global_permissions=GlobalPermissions(read_streams=True)
        )
        created = await iggy_client.create_user(
            username, password, permissions=permissions
        )

        await iggy_client.update_permissions(created.id, None)

        fetched = await iggy_client.get_user(created.id)
        assert fetched is not None
        assert fetched.permissions is None

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_update_permissions_takes_effect_for_new_session(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a permission granted after creation is enforced on next login."""
        username, password = unique_credentials(unique_name)
        created = await iggy_client.create_user(username, password)

        denied_client = await login_fresh_client(username, password)
        with pytest.raises(RuntimeError):
            await denied_client.create_stream(unique_name(prefix="before-grant-"))

        await iggy_client.update_permissions(
            created.id,
            Permissions(global_permissions=GlobalPermissions(manage_streams=True)),
        )

        granted_client = await login_fresh_client(username, password)
        stream_name = unique_name(prefix="after-grant-")
        await granted_client.create_stream(stream_name)
        assert await iggy_client.get_stream(stream_name) is not None

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_user_without_manage_users_cannot_update_permissions(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a user lacking manage_users is denied updating another user."""
        actor_username, actor_password = unique_credentials(unique_name)
        actor = await iggy_client.create_user(actor_username, actor_password)
        target_username, target_password = unique_credentials(unique_name)
        target = await iggy_client.create_user(target_username, target_password)

        actor_client = await login_fresh_client(actor_username, actor_password)
        with pytest.raises(RuntimeError):
            await actor_client.update_permissions(
                target.id,
                Permissions(global_permissions=GlobalPermissions(read_streams=True)),
            )

        await iggy_client.delete_user(actor.id)
        await iggy_client.delete_user(target.id)

    @pytest.mark.asyncio
    async def test_user_with_manage_users_can_update_permissions(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a user granted manage_users can update another user."""
        actor_username, actor_password = unique_credentials(unique_name)
        actor = await iggy_client.create_user(
            actor_username,
            actor_password,
            permissions=Permissions(
                global_permissions=GlobalPermissions(manage_users=True)
            ),
        )
        target_username, target_password = unique_credentials(unique_name)
        target = await iggy_client.create_user(target_username, target_password)

        granted = Permissions(global_permissions=GlobalPermissions(read_streams=True))
        actor_client = await login_fresh_client(actor_username, actor_password)
        await actor_client.update_permissions(target.id, granted)

        fetched = await iggy_client.get_user(target.id)
        assert fetched is not None
        assert fetched.permissions == granted

        await iggy_client.delete_user(actor.id)
        await iggy_client.delete_user(target.id)

    @pytest.mark.asyncio
    async def test_failed_update_leaves_target_permissions_unchanged(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a denied update does not alter the target's permissions."""
        actor_username, actor_password = unique_credentials(unique_name)
        actor = await iggy_client.create_user(actor_username, actor_password)
        target_username, target_password = unique_credentials(unique_name)
        initial = Permissions(global_permissions=GlobalPermissions(read_users=True))
        target = await iggy_client.create_user(
            target_username, target_password, permissions=initial
        )

        actor_client = await login_fresh_client(actor_username, actor_password)
        with pytest.raises(RuntimeError):
            await actor_client.update_permissions(
                target.id,
                Permissions(global_permissions=GlobalPermissions(manage_servers=True)),
            )

        fetched = await iggy_client.get_user(target.id)
        assert fetched is not None
        assert fetched.permissions == initial

        await iggy_client.delete_user(actor.id)
        await iggy_client.delete_user(target.id)

    @pytest.mark.asyncio
    async def test_update_permissions_nonexistent_user_fails(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test update_permissions raises for a non-existent user."""
        with pytest.raises(RuntimeError):
            await iggy_client.update_permissions(
                unique_name(max_bytes=MAX_USERNAME_BYTES),
                Permissions(global_permissions=GlobalPermissions(read_streams=True)),
            )


class TestChangePassword:
    """Test password changes via change_password."""

    @pytest.mark.asyncio
    async def test_change_password_swaps_credentials(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test the new password works for login and the old one is rejected."""
        username, password = unique_credentials(unique_name)
        new_password = unique_name(max_bytes=MAX_PASSWORD_BYTES)
        created = await iggy_client.create_user(username, password)

        await iggy_client.change_password(created.id, password, new_password)

        host, port = get_server_config()
        client = IggyClient(f"{host}:{port}")
        await client.connect()
        await wait_for_ping(client)
        with pytest.raises(RuntimeError):
            await client.login_user(username, password)
        await client.login_user(username, new_password)

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_change_password_rejects_wrong_current_password(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test change_password fails when the current password is wrong."""
        username = unique_name(max_bytes=MAX_USERNAME_BYTES)
        # Keep one byte of headroom so the wrong password stays within the
        # server limit and the failure is about the mismatch, not the length.
        password = unique_name(max_bytes=MAX_PASSWORD_BYTES - 1)
        created = await iggy_client.create_user(username, password)

        with pytest.raises(RuntimeError):
            await iggy_client.change_password(
                created.id, f"{password}x", unique_name(max_bytes=MAX_PASSWORD_BYTES)
            )

        client = await login_fresh_client(username, password)
        await client.ping()

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_user_can_change_own_password(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a user without permissions can change its own password."""
        username, password = unique_credentials(unique_name)
        new_password = unique_name(max_bytes=MAX_PASSWORD_BYTES)
        created = await iggy_client.create_user(username, password)

        client = await login_fresh_client(username, password)
        await client.change_password(created.id, password, new_password)

        relogin = await login_fresh_client(username, new_password)
        await relogin.ping()

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_user_with_manage_users_can_change_other_password(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a user granted manage_users can change another user's password."""
        actor_username, actor_password = unique_credentials(unique_name)
        actor = await iggy_client.create_user(
            actor_username,
            actor_password,
            permissions=Permissions(
                global_permissions=GlobalPermissions(manage_users=True)
            ),
        )
        target_username, target_password = unique_credentials(unique_name)
        target = await iggy_client.create_user(target_username, target_password)
        new_password = unique_name(max_bytes=MAX_PASSWORD_BYTES)

        actor_client = await login_fresh_client(actor_username, actor_password)
        await actor_client.change_password(target.id, target_password, new_password)

        relogin = await login_fresh_client(target_username, new_password)
        await relogin.ping()

        await iggy_client.delete_user(actor.id)
        await iggy_client.delete_user(target.id)

    @pytest.mark.asyncio
    async def test_failed_password_change_leaves_target_credentials_valid(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test a user lacking manage_users is denied and old credentials stay valid."""
        actor_username, actor_password = unique_credentials(unique_name)
        actor = await iggy_client.create_user(actor_username, actor_password)
        target_username, target_password = unique_credentials(unique_name)
        target = await iggy_client.create_user(target_username, target_password)

        actor_client = await login_fresh_client(actor_username, actor_password)
        with pytest.raises(RuntimeError):
            await actor_client.change_password(
                target.id, target_password, unique_name(max_bytes=MAX_PASSWORD_BYTES)
            )

        target_client = await login_fresh_client(target_username, target_password)
        await target_client.ping()

        await iggy_client.delete_user(actor.id)
        await iggy_client.delete_user(target.id)

    @pytest.mark.parametrize(
        "new_password",
        ["a" * (MIN_PASSWORD_BYTES - 1), "a" * (MAX_PASSWORD_BYTES + 1)],
        ids=["too-short", "too-long"],
    )
    @pytest.mark.asyncio
    async def test_change_password_rejects_out_of_bounds_new_password(
        self, iggy_client: IggyClient, unique_name, new_password
    ):
        """Test change_password rejects new passwords outside the 3-100 byte range."""
        username, password = unique_credentials(unique_name)
        created = await iggy_client.create_user(username, password)

        with pytest.raises(RuntimeError):
            await iggy_client.change_password(created.id, password, new_password)

        client = await login_fresh_client(username, password)
        await client.ping()

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_change_password_nonexistent_user_fails(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test change_password raises for a non-existent user."""
        with pytest.raises(RuntimeError):
            await iggy_client.change_password(
                unique_name(max_bytes=MAX_USERNAME_BYTES),
                unique_name(max_bytes=MAX_PASSWORD_BYTES),
                unique_name(max_bytes=MAX_PASSWORD_BYTES),
            )


class TestLogoutUser:
    """Test session termination via logout_user."""

    @pytest.mark.asyncio
    async def test_logout_user_ends_the_session(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test authenticated calls fail after logout."""
        username, password = unique_credentials(unique_name)
        created = await iggy_client.create_user(
            username,
            password,
            permissions=Permissions(
                global_permissions=GlobalPermissions(read_users=True)
            ),
        )

        client = await login_fresh_client(username, password)
        assert await client.get_user(username) is not None

        await client.logout_user()

        with pytest.raises(RuntimeError):
            await client.get_user(username)

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_logout_twice_fails(self, iggy_client: IggyClient, unique_name):
        """Test a second logout on the same session raises."""
        username, password = unique_credentials(unique_name)
        created = await iggy_client.create_user(username, password)

        client = await login_fresh_client(username, password)
        await client.logout_user()

        with pytest.raises(RuntimeError):
            await client.logout_user()

        await iggy_client.delete_user(created.id)

    @pytest.mark.asyncio
    async def test_login_after_logout_restores_the_session(
        self, iggy_client: IggyClient, unique_name
    ):
        """Test the same client can log in again after logging out."""
        username, password = unique_credentials(unique_name)
        created = await iggy_client.create_user(
            username,
            password,
            permissions=Permissions(
                global_permissions=GlobalPermissions(read_users=True)
            ),
        )

        client = await login_fresh_client(username, password)
        await client.logout_user()

        await client.login_user(username, password)
        assert await client.get_user(username) is not None

        await iggy_client.delete_user(created.id)
