from unittest import TestCase
from pygeai.organization.clients import OrganizationClient
from pygeai.core.common.exceptions import APIResponseError 


class TestOrgGetProjectTokensIntegration(TestCase):
    __token_attrs = [
        'description', 'id', 'name', 'status', 'timestamp'
    ]    

    def setUp(self):
        """
        Set up the test environment.
        """
        self.organization_client = OrganizationClient(alias="org")
        self.project_id = "be4889df-cacc-4e6f-b3bb-153c4ac0d168"


    def __get_project_tokens(self, project_id=None):
        """
        Helper method to call get_project_tokens with default or custom parameters.
        """
        return self.organization_client.get_project_tokens(
            project_id=project_id if project_id is not None else self.project_id
        )


    def test_get_project_tokens_valid_project_id(self):
        """Test successful retrieval of project tokens with valid project ID."""
        response = self.__get_project_tokens()

        # Validate response structure
        self.assertIn("tokens", response, "Response should have a 'tokens' key")
                
        # If there are tokens, validate their structure
        for token in response["tokens"]:
            for token_attr in self.__token_attrs:
                self.assertIn(token_attr, token, f"Token should have a '{token_attr}' key")
            
            # Validate data types
            self.assertIsInstance(token["id"], str, "Token ID should be string")
            self.assertIsInstance(token["name"], str, "Token name should be string")
            self.assertIsInstance(token["status"], str, "Token status should be string")


    def test_get_project_tokens_invalid_project_id(self):
        """Test error when using invalid project ID."""
        with self.assertRaises(APIResponseError) as exception:
            self.__get_project_tokens(project_id="invalid-project-id")

        self.assertIn(
            "Project not in Organization",
            str(exception.exception)
        )


    def test_get_project_tokens_empty_project_id(self):
        """Test error when project ID is empty."""
        with self.assertRaises(APIResponseError) as exception:
            self.__get_project_tokens(project_id="")

        self.assertIn(
            "Not Found",
            str(exception.exception),
            "Expected error about empty project ID"
        )


    def test_get_project_tokens_unauthorized_access(self):
        """Test error when user doesn't have access to the project."""
        # Create a client with invalid credentials
        unauthorized_client = OrganizationClient(api_key="invalid", base_url="https://api.beta.saia.ai")
        
        with self.assertRaises(APIResponseError) as exception:
            unauthorized_client.get_project_tokens(project_id=self.project_id)

        self.assertIn(
            "Unauthorized",
            str(exception.exception),
            "Expected authorization-related error message"
        )


    def test_get_project_tokens_no_access_to_project(self):
        """Test error when user has valid credentials but no access to specific project."""
        # Project ID that exists but user doesn't have access to
        restricted_project_id = "6f5c69f1-232d-47d6-84f8-8bec87946bbc"
        
        with self.assertRaises(APIResponseError) as exception:
            self.__get_project_tokens(project_id=restricted_project_id)

        self.assertIn(
            "Project not in Organization",
            str(exception.exception),
            "Expected access-related error message"
        )

    
    def test_get_project_tokens_null_project_id(self):
        """Test error when project ID is None."""
        with self.assertRaises((APIResponseError, TypeError)) as exception:
            self.__get_project_tokens(project_id="")

        self.assertIn(
            "Not Found",
             str(exception.exception),
            "Expected error about null project ID"
        )