import unittest
import uuid
from unittest import mock

from bittrade_client.client.client import BittradeClient
from vault_client.client.client_definition import VaultClient
from vault_client.client.conio_user import ConioUser
from vault_client.generated_protobuf import vault_pb2

from conio_sdk.common import exceptions
from conio_sdk.services.conio import UserLevel
from conio_sdk.services.conio.explicit_fees.bittrade_vault_explicit_fees_service import BittradeVaultExplicitFeesService


class TestBittradeVaultExplicitFeesService(unittest.TestCase):
    def setUp(self) -> None:
        self.bittrade_client = mock.create_autospec(BittradeClient)
        self.vault_client = mock.create_autospec(VaultClient)
        self.sut = BittradeVaultExplicitFeesService(
            self.bittrade_client, self.vault_client
        )
        self.bittrade_client.get_explicit_fees.return_value = (
            mock.Mock(
                explicit_fees_id='explicit_fees_1',
                description='level 1'
            ),
            mock.Mock(
                explicit_fees_id='explicit_fees_2',
                description='level 2'
            ),
            mock.Mock(
                explicit_fees_id='explicit_fees_3',
                description='level 3'
            )
        )

    def test(self):
        user = ConioUser(
            data={
                'reference_key_id': str(uuid.uuid4()),
                'email': 'test@conio.com',
                'external_references': [str(uuid.uuid4())],
                'status': vault_pb2.ACTIVE,
                'explicit_fees_ids': None
            }
        )

        user_level = UserLevel('level 3')
        self.sut.associate_explicit_fees(user, user_level)
        self.vault_client.save_user_info_v2.assert_called_once_with(
            {
                'explicit_fees_ids': ['explicit_fees_3']
            },
            user.reference_key_id
        )

    def test_explicit_fees_already_associated(self):
        user = ConioUser(
            data={
                'reference_key_id': str(uuid.uuid4()),
                'email': 'test@conio.com',
                'external_references': [str(uuid.uuid4())],
                'status': vault_pb2.ACTIVE,
                'explicit_fees_ids': ['explicit_fees_3']
            }
        )

        user_level = UserLevel('level 3')
        self.sut.associate_explicit_fees(user, user_level)
        self.assertEqual(0, self.vault_client.save_user_info_v2.call_count)

    def test_missing_level(self):
        user = ConioUser(
            data={
                'reference_key_id': str(uuid.uuid4()),
                'email': 'test@conio.com',
                'external_references': [str(uuid.uuid4())],
                'status': vault_pb2.ACTIVE,
                'explicit_fees_ids': None
            }
        )

        user_level = UserLevel('level 4')
        with self.assertRaises(exceptions.CouldNotFindExplicitFeesExceptionForUserLevel):
            self.sut.associate_explicit_fees(user, user_level)
        self.assertEqual(0, self.vault_client.save_user_info_v2.call_count)
