import os
import unittest
from urllib.error import HTTPError
from urllib.request import Request
from meteoclimatic.exceptions import StationNotFound, MeteoclimaticError
from meteoclimatic import MeteoclimaticClient
from meteoclimatic import __version__
from unittest.mock import patch, MagicMock


class TestMeteoclimaticClient(unittest.TestCase):

    def setUp(self):
        self.client = MeteoclimaticClient()

    @patch('meteoclimatic.client.urlopen', autospec=True)
    def test_get_station_info_ok(self, mock_urlopen):
        f = open(os.path.join(os.path.dirname(
            __file__), "feeds", "full_station.xml"))
        mock_urlopen.return_value.read.return_value = f

        res = self.client.weather_at_station("ESCAT4300000043206B")

        # Verify urlopen was called with a Request object
        self.assertEqual(mock_urlopen.call_count, 1)
        called_request = mock_urlopen.call_args[0][0]
        self.assertIsInstance(called_request, Request)
        self.assertEqual(called_request.full_url, 
                        "https://www.meteoclimatic.net/feed/rss/ESCAT4300000043206B")
        self.assertEqual(called_request.get_header("User-agent"), 
                        f"pymeteoclimatic/{__version__}")
        self.assertEqual(res.station.code, "ESCAT4300000043206B")

    @patch('meteoclimatic.client.urlopen', autospec=True)
    def test_get_station_info_no_xml(self, mock_urlopen):
        mock_urlopen.return_value.read.return_value = ""

        with self.assertRaises(StationNotFound) as error:
            self.client.weather_at_station("ESCAT4300000043206B")
        self.assertEqual(error.exception.station_code, "ESCAT4300000043206B")
        self.assertEqual(str(
            error.exception), "Station code ESCAT4300000043206B did not return any item")

    @patch('meteoclimatic.client.urlopen', autospec=True)
    def test_get_station_info_404(self, mock_urlopen):
        mock_urlopen.side_effect = HTTPError("", 404, "Not Found", [], None)

        with self.assertRaises(MeteoclimaticError) as error:
            self.client.weather_at_station("ESCAT4300000043206B")
        self.assertEqual(str(
            error.exception), "Error fetching station data [status_code=404]")

    @patch('meteoclimatic.client.urlopen', autospec=True)
    def test_user_agent_header_is_set(self, mock_urlopen):
        """Test that the User-Agent header is correctly set with version"""
        mock_response = MagicMock()
        mock_response.read.return_value = open(os.path.join(
            os.path.dirname(__file__), "feeds", "full_station.xml")).read()
        mock_urlopen.return_value = mock_response

        self.client.weather_at_station("ESCAT4300000043206B")

        # Verify the Request object has the correct User-Agent
        called_request = mock_urlopen.call_args[0][0]
        self.assertIsInstance(called_request, Request)
        user_agent = called_request.get_header("User-agent")
        self.assertEqual(user_agent, f"pymeteoclimatic/{__version__}")
        # Verify it follows the expected format
        self.assertTrue(user_agent.startswith("pymeteoclimatic/"))
