"""The tests for the uk_transport platform."""
import re
import unittest

import requests_mock

from homeassistant.components.uk_transport.sensor import (
    ATTR_ATCOCODE,
    ATTR_CALLING_AT,
    ATTR_LOCALITY,
    ATTR_NEXT_BUSES,
    ATTR_NEXT_TRAINS,
    ATTR_STATION_CODE,
    ATTR_STOP_NAME,
    CONF_API_APP_ID,
    CONF_API_APP_KEY,
    UkTransportSensor,
)
from homeassistant.setup import setup_component
from homeassistant.util.dt import now

from tests.async_mock import patch
from tests.common import get_test_home_assistant, load_fixture

BUS_ATCOCODE = "340000368SHE"
BUS_DIRECTION = "Wantage"
TRAIN_STATION_CODE = "WIM"
TRAIN_DESTINATION_NAME = "WAT"

VALID_CONFIG = {
    "platform": "uk_transport",
    CONF_API_APP_ID: "foo",
    CONF_API_APP_KEY: "ebcd1234",
    "queries": [
        {"mode": "bus", "origin": BUS_ATCOCODE, "destination": BUS_DIRECTION},
        {
            "mode": "train",
            "origin": TRAIN_STATION_CODE,
            "destination": TRAIN_DESTINATION_NAME,
        },
    ],
}


class TestUkTransportSensor(unittest.TestCase):
    """Test the uk_transport platform."""

    def setUp(self):
        """Initialize values for this testcase class."""
        self.hass = get_test_home_assistant()
        self.config = VALID_CONFIG
        self.addCleanup(self.hass.stop)

    @requests_mock.Mocker()
    def test_bus(self, mock_req):
        """Test for operational uk_transport sensor with proper attributes."""
        with requests_mock.Mocker() as mock_req:
            uri = re.compile(UkTransportSensor.TRANSPORT_API_URL_BASE + "*")
            mock_req.get(uri, text=load_fixture("uk_transport_bus.json"))
            assert setup_component(self.hass, "sensor", {"sensor": self.config})
            self.hass.block_till_done()

        bus_state = self.hass.states.get("sensor.next_bus_to_wantage")

        assert type(bus_state.state) == str
        assert bus_state.name == f"Next bus to {BUS_DIRECTION}"
        assert bus_state.attributes.get(ATTR_ATCOCODE) == BUS_ATCOCODE
        assert bus_state.attributes.get(ATTR_LOCALITY) == "Harwell Campus"
        assert bus_state.attributes.get(ATTR_STOP_NAME) == "Bus Station"
        assert len(bus_state.attributes.get(ATTR_NEXT_BUSES)) == 2

        direction_re = re.compile(BUS_DIRECTION)
        for bus in bus_state.attributes.get(ATTR_NEXT_BUSES):
            print(bus["direction"], direction_re.match(bus["direction"]))
            assert direction_re.search(bus["direction"]) is not None

    @requests_mock.Mocker()
    def test_train(self, mock_req):
        """Test for operational uk_transport sensor with proper attributes."""
        with requests_mock.Mocker() as mock_req, patch(
            "homeassistant.util.dt.now", return_value=now().replace(hour=13)
        ):
            uri = re.compile(UkTransportSensor.TRANSPORT_API_URL_BASE + "*")
            mock_req.get(uri, text=load_fixture("uk_transport_train.json"))
            assert setup_component(self.hass, "sensor", {"sensor": self.config})
            self.hass.block_till_done()

        train_state = self.hass.states.get("sensor.next_train_to_WAT")

        assert type(train_state.state) == str
        assert train_state.name == f"Next train to {TRAIN_DESTINATION_NAME}"
        assert train_state.attributes.get(ATTR_STATION_CODE) == TRAIN_STATION_CODE
        assert train_state.attributes.get(ATTR_CALLING_AT) == TRAIN_DESTINATION_NAME
        assert len(train_state.attributes.get(ATTR_NEXT_TRAINS)) == 25

        assert (
            train_state.attributes.get(ATTR_NEXT_TRAINS)[0]["destination_name"]
            == "London Waterloo"
        )
        assert train_state.attributes.get(ATTR_NEXT_TRAINS)[0]["estimated"] == "06:13"
