from evrouting.charge import shortest_path

from ..config import (
    edge_case,
    edge_case_start_node_no_cs,
    edge_case_a_slow,
    init_config
)


class TestRoutes:

    def test_shortest_path_charge_at_s_and_a(self):
        """Charging at s."""
        result = shortest_path(**init_config(edge_case))

        assert result['trip_time'] == 3.5
        assert result['path'] == [(0, 0), (0, 1), (1, 2), (1, 2.5), (2, 3.5)]

    def test_shortest_path_charge_at_s_only(self):
        """Charging at s."""
        result = shortest_path(**init_config(edge_case_a_slow))

        assert result['trip_time'] == 3
        assert result['path'] == [(0, 0), (0, 2), (2, 3)]

    def test_shortest_path_no_charge_s_path_t(self):
        """No charging at s but enough initial SoC to go to t directly."""
        conf = init_config(edge_case_start_node_no_cs)
        conf['initial_soc'] = 4
        result = shortest_path(**conf)

        assert result['trip_time'] == 1
        assert result['path'] == [(0, 0), (2, 1)]

    def test_shortest_path_no_charge_s_path_a(self):
        """No charging at s but just enough SoC to go to t via a."""
        conf = init_config(edge_case_start_node_no_cs)
        conf['initial_soc'] = 2
        result = shortest_path(**conf)

        assert result['trip_time'] == 2
        assert result['path'] == [(0, 0), (1, 1), (2, 2)]


class TestWithFinalSoC:

    def test_shortest_path_charge_at_s_and_a(self):
        """Charging at s."""
        conf = init_config(edge_case)
        conf['final_soc'] = 3
        result = shortest_path(**conf)

        assert result['trip_time'] == 5
        assert result['path'] == [(0, 0), (0, 1), (1, 2), (1, 4), (2, 5)]

    def test_path_impossilbe(self):
        """Not possible to end with full battery."""
        conf = init_config(edge_case)
        conf['final_soc'] = 4
        result = shortest_path(**conf)

        assert result['trip_time'] is None
        assert result['path'] == []

    def test_shortest_path_charge_at_s_only(self):
        """Charging at s and a to reach final_soc."""
        conf = init_config(edge_case_a_slow)
        conf['final_soc'] = 3
        result = shortest_path(**conf)

        assert result['trip_time'] == 5
        assert result['path'] == [(0, 0), (0, 2), (1, 3), (1, 4), (2, 5)]

    def test_shortest_path_no_charge_s_path_t(self):
        """No charging at s but initial soc."""
        conf = init_config(edge_case_start_node_no_cs)
        conf['initial_soc'] = 4
        conf['final_soc'] = 3
        result = shortest_path(**conf)

        assert result['trip_time'] == 2.5
        assert result['path'] == [(0, 0), (1, 1), (1, 1.5), (2, 2.5)]