# coding: utf-8

"""
    Kestra EE

    All API operations, except for Superadmin-only endpoints, require a tenant identifier in the HTTP path.<br/> Endpoints designated as Superadmin-only are not tenant-scoped.

    The version of the OpenAPI document: v1
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


import unittest
from kestrapy import (Configuration,
                      KestraClient,
                      IAMUserControllerApiCreateOrUpdateUserRequest,
                      IAMTenantAccessControllerUserApiAutocomplete,
                      CreateApiTokenRequest,
                      MeControllerApiUpdatePasswordRequest,
                      IAMUserControllerApiPatchUserPasswordRequest,
                      ApiPatchSuperAdminRequest,
                      IAMUserGroupControllerApiUpdateUserGroupsRequest,
                      IAMGroupControllerApiCreateGroupRequest
                      )

class TestUsersApi(unittest.TestCase):
    """UsersApi unit test stubs"""

    def setUp(self) -> None:
        configuration = Configuration()
        configuration.host = "http://localhost:9902"
        configuration.username = "root@root.com"
        configuration.password = "Root!1234"

        self.kestra_client = KestraClient(configuration)
        self.tenant = "main"


    def tearDown(self) -> None:
        pass

    def test_autocomplete_users(self) -> None:
        """Test case for autocomplete_users

        List users for autocomplete
        """
        email = "test_autocomplete_users@kestra.io"
        # create a user to autocomplete
        user = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=email
        )

        created_user = self.kestra_client.users.create_user(
            iam_user_controller_api_create_or_update_user_request=user
        )
        # Create a tenantAccess by adding user to a group
        group = IAMGroupControllerApiCreateGroupRequest(
            name="test_autocomplete_users",
            description="An example group"
        )

        created_group = self.kestra_client.groups.create_group(
            tenant=self.tenant,
            iam_group_controller_api_create_group_request=group
        )

        self.kestra_client.groups.add_user_to_group(
            tenant=self.tenant,
            id=created_group.id,
            user_id=created_user.id
        )

        autocomplete_req = IAMTenantAccessControllerUserApiAutocomplete(q=email)

        results = self.kestra_client.users.autocomplete_users(
            tenant=self.tenant,
            iam_tenant_access_controller_user_api_autocomplete=autocomplete_req
        )

        assert any(getattr(r, 'username', None) == created_user.email for r in results)

    def test_create_api_tokens_for_user(self) -> None:
        """Test case for create_api_tokens_for_user

        Create new API Token for a specific user
        """
        name_base = "test_create_api_tokens_for_user"
        # create user
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io"
        )
        created_user = self.kestra_client.users.create_user(
            iam_user_controller_api_create_or_update_user_request=user_req
        )

        # token name must match regex: use lowercase and hyphens
        token_req = CreateApiTokenRequest(
            name=name_base.replace("_", "-"),
            description="token for test_create_api_tokens_for_user",
        )
        token = self.kestra_client.users.create_api_tokens_for_user(
            id=created_user.id,
            create_api_token_request=token_req
        )

        assert getattr(token, 'id', None) is not None

    def test_create_user(self) -> None:
        """Test case for create_user

        Create a new user account
        """
        name_base = "test_create_user"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io",
            first_name=name_base,
            password="Password!234"
        )

        created = self.kestra_client.users.create_user(
            iam_user_controller_api_create_or_update_user_request=user_req
        )
        assert created.email == user_req.email

        # cleanup
        try:
            self.kestra_client.users.delete_user(id=created.id)
        except Exception:
            pass

    def test_delete_api_token_for_user(self) -> None:
        """Test case for delete_api_token_for_user

        Delete an API Token for specific user and token id
        """
        name_base = "test_delete_api_token_for_user"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io"
        )
        created_user = self.kestra_client.users.create_user(
            iam_user_controller_api_create_or_update_user_request=user_req
        )

        token_req = CreateApiTokenRequest(
            name=name_base.replace("_", "-"),
            description="token to delete",
        )
        token = self.kestra_client.users.create_api_tokens_for_user(id=created_user.id, create_api_token_request=token_req)

        self.kestra_client.users.delete_api_token_for_user(id=created_user.id, token_id=token.id)

    def test_delete_refresh_token(self) -> None:
        """Delete a user refresh token

        This operation is superadmin-only; create a user and attempt to delete refresh token (may be no-op)
        """
        name_base = "test_delete_refresh_token"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io"
        )
        created_user = self.kestra_client.users.create_user(
            iam_user_controller_api_create_or_update_user_request=user_req
        )

        # call delete_refresh_token (no explicit token id required)
        self.kestra_client.users.delete_refresh_token(id=created_user.id)

        # cleanup
        try:
            self.kestra_client.users.delete_user(id=created_user.id)
        except Exception:
            pass

    def test_delete_user(self) -> None:
        """Delete a user"""
        name_base = "test_delete_user"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io"
        )
        created_user = self.kestra_client.users.create_user(
            iam_user_controller_api_create_or_update_user_request=user_req
        )

        self.kestra_client.users.delete_user(id=created_user.id)

    def test_delete_user_auth_method(self) -> None:
        """Update user password (delete auth method) - use patch restricted as placeholder"""
        name_base = "test_delete_user_auth_method"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io",
            password="Password!234"
        )
        created_user = self.kestra_client.users.create_user(
            iam_user_controller_api_create_or_update_user_request=user_req
        )

        patched = self.kestra_client.users.delete_user_auth_method(
            id=created_user.id,
            auth=created_user.auths[0].id
        )
        assert getattr(patched, 'id', None) == created_user.id

    def test_get_user(self) -> None:
        """Get a user"""
        name_base = "test_get_user"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io"
        )
        created_user = self.kestra_client.users.create_user(
            iam_user_controller_api_create_or_update_user_request=user_req
        )

        fetched = self.kestra_client.users.user(id=created_user.id)
        assert fetched.id == created_user.id

        # cleanup
        try:
            self.kestra_client.users.delete_user(id=created_user.id)
        except Exception:
            pass

    def test_list_api_tokens_for_user(self) -> None:
        """Test case for list_api_tokens_for_user

        List API tokens for a specific user
        """
        name_base = "test_list_api_tokens_for_user"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io"
        )
        created_user = self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        token_req = CreateApiTokenRequest(name=name_base.replace("_", "-"))
        created_token = self.kestra_client.users.create_api_tokens_for_user(id=created_user.id, create_api_token_request=token_req)

        tokens = self.kestra_client.users.list_api_tokens_for_user(id=created_user.id)
        assert any(getattr(t, 'id', None) == created_token.id for t in tokens.results)

    def test_list_users(self) -> None:
        """Retrieve users"""
        name_base = "test_list_users"
        # create a user
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io"
        )
        created_user = self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        results = self.kestra_client.users.list_users(page=1, size=50, q=name_base)
        assert any(getattr(r, 'id', None) == created_user.id for r in results.results)

    def test_list_users_fetch_all_pages(self) -> None:
        """Retrieve users without query"""
        name_base = "test_list_users_no_query"
        for i in range(60):
            user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
                email = f"{name_base}_{i}@kestra.io"
            )
            self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        users = []
        page = 1
        size = 25

        while True:
            results = self.kestra_client.users.list_users(page=page, size=size)
            users.extend(results.results)
            if len(results.results) < size:
                break
            page += 1

        assert len(users) >= 60

    def test_patch_user(self) -> None:
        """Update user details"""
        name_base = "test_patch_user"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io",
            first_name="Old"
        )
        created_user = self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        update_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=created_user.email,
            first_name="New"
        )
        updated = self.kestra_client.users.update_user(id=created_user.id, iam_user_controller_api_create_or_update_user_request=update_req)
        assert getattr(updated, 'first_name', None) == "New" or getattr(updated, 'firstName', None) == "New"

        # cleanup
        try:
            self.kestra_client.users.delete_user(id=created_user.id)
        except Exception:
            pass

    def test_patch_user_password(self) -> None:
        """Update user password"""
        name_base = "test_patch_user_password"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io",
            password="OldPass!1"
        )
        created_user = self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        password_req = IAMUserControllerApiPatchUserPasswordRequest(password="NewPass!1")
        patched = self.kestra_client.users.patch_user_password(id=created_user.id, iam_user_controller_api_patch_user_password_request=password_req)
        assert getattr(patched, 'id', None) == created_user.id

    def test_patch_user_super_admin(self) -> None:
        """Update user superadmin privileges"""
        name_base = "test_patch_user_super_admin"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io"
        )
        created_user = self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        patch = ApiPatchSuperAdminRequest(super_admin=True)
        self.kestra_client.users.patch_user_super_admin(id=created_user.id, api_patch_super_admin_request=patch)

        fetched = self.kestra_client.users.user(id=created_user.id)
        assert getattr(fetched, 'super_admin', None) is True

    def test_update_current_user_password(self) -> None:
        """Update authenticated user password for a dedicated test user (do not modify admin user)

        This test creates a new user with a known password, creates a client authenticated as that user,
        updates the user's password and then reverts it, and finally cleans up the created user.
        If creating the user is unauthorized, the test is skipped.
        """
        name_base = "test_update_current_user_password"
        email = f"{name_base}@kestra.io"
        initial_password = "InitialPass!1"
        changed_password = "ChangedPass!1"

        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(email=email, password=initial_password, tenants=[self.tenant])
        created_user = self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        # create a client authenticated as the test user
        user_conf = Configuration()
        user_conf.host = "http://localhost:9902"
        user_conf.username = email
        user_conf.password = initial_password
        user_client = KestraClient(user_conf)

        # change password using the dedicated client
        pwd_req = MeControllerApiUpdatePasswordRequest(old_password=initial_password, new_password=changed_password)
        user_client.users.update_current_user_password(me_controller_api_update_password_request=pwd_req)

        # update client and make sure he can change his password again using the new one
        user_conf.password = changed_password
        user_client = KestraClient(user_conf)

        # revert the password back
        revert_req = MeControllerApiUpdatePasswordRequest(old_password=changed_password, new_password=initial_password)
        user_client.users.update_current_user_password(me_controller_api_update_password_request=revert_req)

    def test_update_user(self) -> None:
        """Update a user account"""
        name_base = "test_update_user"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io",
            first_name="Before"
        )
        created_user = self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        update_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=created_user.email,
            first_name="After"
        )
        updated = self.kestra_client.users.update_user(id=created_user.id, iam_user_controller_api_create_or_update_user_request=update_req)
        assert getattr(updated, 'first_name', None) == "After" or getattr(updated, 'firstName', None) == "After"

    def test_update_user_groups(self) -> None:
        """Update the list of groups a user belongs to for the given tenant"""

        group = IAMGroupControllerApiCreateGroupRequest(
            name="test_update_user_groups",
            description="An example group"
        )

        created_group = self.kestra_client.groups.create_group(
            tenant=self.tenant,
            iam_group_controller_api_create_group_request=group
        )

        name_base = "test_update_user_groups"
        user_req = IAMUserControllerApiCreateOrUpdateUserRequest(
            email=f"{name_base}@kestra.io",
            tenants=[self.tenant]
        )
        created_user = self.kestra_client.users.create_user(iam_user_controller_api_create_or_update_user_request=user_req)

        groups_req = IAMUserGroupControllerApiUpdateUserGroupsRequest(group_ids=[created_group.id])
        self.kestra_client.users.update_user_groups(tenant=self.tenant, id=created_user.id, iam_user_group_controller_api_update_user_groups_request=groups_req)



if __name__ == '__main__':
    unittest.main()
