import unittest
from unittest.mock import patch, MagicMock
from pygeai.core.omni.clients import OmniParserClient


class TestOmniParserClient(unittest.TestCase):

    def setUp(self):
        self.client = OmniParserClient()
        self.file_path = "test_file.pdf"

    @patch('pygeai.core.omni.clients.Path')
    @patch('pygeai.core.base.clients.BaseClient.api_service')
    def test_process_file_basic(self, mock_api_service, mock_path):
        mock_file_obj = MagicMock()
        mock_path_instance = MagicMock()
        mock_path_instance.is_file.return_value = True
        mock_path_instance.open.return_value = mock_file_obj
        mock_path.return_value = mock_path_instance

        mock_response = MagicMock()
        mock_response.json.return_value = {
            "status": "success",
            "parts": [{"text": "Sample text", "type": "NarrativeText"}],
            "requestId": "test-123"
        }
        mock_response.status_code = 200
        mock_api_service.post_files_multipart.return_value = mock_response

        result = self.client.process_file(file_path=self.file_path)

        mock_api_service.post_files_multipart.assert_called_once()
        self.assertEqual(result["status"], "success")
        self.assertIn("parts", result)

    @patch('pygeai.core.omni.clients.Path')
    @patch('pygeai.core.base.clients.BaseClient.api_service')
    def test_process_file_with_all_parameters(self, mock_api_service, mock_path):
        mock_file_obj = MagicMock()
        mock_path_instance = MagicMock()
        mock_path_instance.is_file.return_value = True
        mock_path_instance.open.return_value = mock_file_obj
        mock_path.return_value = mock_path_instance

        mock_response = MagicMock()
        mock_response.json.return_value = {
            "status": "success",
            "parts": [{"text": "Sample text", "page": 1}],
            "requestId": "test-123"
        }
        mock_response.status_code = 200
        mock_api_service.post_files_multipart.return_value = mock_response

        result = self.client.process_file(
            file_path=self.file_path,
            start_page=1,
            end_page=5,
            hi_res_mode=True,
            structure="table",
            dialogue=False,
            output_format="markdown",
            password="secret",
            cache=True
        )

        mock_api_service.post_files_multipart.assert_called_once()
        call_args = mock_api_service.post_files_multipart.call_args
        self.assertIn("startPage", call_args[1]["data"])
        self.assertIn("endPage", call_args[1]["data"])
        self.assertEqual(call_args[1]["data"]["hiResMode"], "true")
        self.assertEqual(call_args[1]["data"]["structure"], "table")
        self.assertEqual(call_args[1]["headers"]["X-Saia-Cache-Enabled"], "true")

    @patch('pygeai.core.omni.clients.Path')
    def test_process_file_not_found(self, mock_path):
        mock_path_instance = MagicMock()
        mock_path_instance.is_file.return_value = False
        mock_path.return_value = mock_path_instance

        with self.assertRaises(FileNotFoundError):
            self.client.process_file(file_path="nonexistent.pdf")

    @patch('pygeai.core.omni.clients.Path')
    def test_process_file_invalid_page_range(self, mock_path):
        mock_path_instance = MagicMock()
        mock_path_instance.is_file.return_value = True
        mock_path.return_value = mock_path_instance

        with self.assertRaises(ValueError):
            self.client.process_file(
                file_path=self.file_path,
                start_page=10,
                end_page=5
            )

    @patch('pygeai.core.omni.clients.Path')
    def test_process_file_negative_page(self, mock_path):
        mock_path_instance = MagicMock()
        mock_path_instance.is_file.return_value = True
        mock_path.return_value = mock_path_instance

        with self.assertRaises(ValueError):
            self.client.process_file(
                file_path=self.file_path,
                start_page=-1
            )
