class test_RoadLiner(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        self.esminiPath = self.configuration.get("esminipath")
        self.roadBuilder = RoadBuilder()
        self.laneBuilder = LaneBuilder()
        self.laneLinker = LaneLinker()
        self.straightRoadBuilder = StraightRoadBuilder()
        self.curveBuilder = CurveRoadBuilder()
        self.roadLinker = RoadLinker()

    def test_getAngleBetweenStraightRoads(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        connectionRoad = self.curveBuilder.create(1,
                                                  np.pi / 4,
                                                  isJunction=True,
                                                  curvature=0.2,
                                                  n_lanes=1)
        roads.append(connectionRoad)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=2))

        connectionRoad2 = self.curveBuilder.create(3,
                                                   np.pi / 2,
                                                   isJunction=True,
                                                   curvature=0.1,
                                                   n_lanes=1)
        roads.append(connectionRoad2)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(4,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)

        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.end)
        roads[1].addExtendedSuccessor(roads[2], 0, pyodrx.ContactPoint.start)

        roads[2].addExtendedPredecessor(roads[1], 0, pyodrx.ContactPoint.end)
        roads[2].addExtendedSuccessor(roads[3], 0, pyodrx.ContactPoint.start)

        roads[3].addExtendedPredecessor(roads[2], 0, pyodrx.ContactPoint.start)
        roads[3].addExtendedSuccessor(roads[4], 0, pyodrx.ContactPoint.start)

        roads[4].addExtendedPredecessor(roads[3], 0, pyodrx.ContactPoint.end)

        self.laneBuilder.createLanesForConnectionRoad(connectionRoad, roads[0],
                                                      roads[2])
        self.laneBuilder.createLanesForConnectionRoad(connectionRoad2,
                                                      roads[2], roads[4])

        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[2])))
        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[4])))
        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[2], roads[4])))

        # xmlPath = f"output/test_DifferentLaneConfigurations.xodr"
        # odr.write_xml(xmlPath)

    def test_StartEnd(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        connectionRoad = self.curveBuilder.create(1,
                                                  np.pi / 4,
                                                  isJunction=True,
                                                  curvature=0.1,
                                                  n_lanes=1)
        roads.append(connectionRoad)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)

        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.start)
        roads[1].addExtendedSuccessor(roads[2], 0, pyodrx.ContactPoint.start)

        roads[2].addExtendedPredecessor(roads[1], 0, pyodrx.ContactPoint.end)

        self.laneBuilder.createLanesForConnectionRoad(connectionRoad, roads[0],
                                                      roads[2])

        odrName = "test_StartEnd"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[2])))

        xmlPath = f"output/test_StartEnd.xodr"
        odr.write_xml(xmlPath)

    def test_fails(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        connectionRoad = self.curveBuilder.create(1,
                                                  np.pi / 4,
                                                  isJunction=True,
                                                  curvature=0.2,
                                                  n_lanes=1)
        roads.append(connectionRoad)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=2))

        connectionRoad2 = self.curveBuilder.create(3,
                                                   np.pi / 2,
                                                   isJunction=True,
                                                   curvature=0.1,
                                                   n_lanes=1)
        roads.append(connectionRoad2)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(4,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=3))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)

        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.end)
        roads[1].addExtendedSuccessor(roads[2], 0, pyodrx.ContactPoint.start)

        roads[2].addExtendedPredecessor(roads[1], 0, pyodrx.ContactPoint.end)
        roads[2].addExtendedSuccessor(roads[3], 0, pyodrx.ContactPoint.start)

        roads[3].addExtendedPredecessor(roads[2], 0, pyodrx.ContactPoint.start)
        roads[3].addExtendedSuccessor(roads[4], 0, pyodrx.ContactPoint.start)

        roads[4].addExtendedPredecessor(roads[3], 0, pyodrx.ContactPoint.end)

        self.laneBuilder.createLanesForConnectionRoad(connectionRoad, roads[0],
                                                      roads[2])
        self.laneBuilder.createLanesForConnectionRoad(connectionRoad2,
                                                      roads[2], roads[4])

        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[2])))
        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[4])))
        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[2], roads[4])))
class test_LaneBuilder(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        self.esminiPath = self.configuration.get("esminipath")
        self.roadBuilder = RoadBuilder()
        self.laneBuilder = LaneBuilder()
        self.laneLinker = LaneLinker()
        self.straightRoadBuilder = StraightRoadBuilder()

    def test_RightLane(self):
        # test scenario for connection road

        roads = []
        roads.append(pyodrx.create_straight_road(0, 10))
        # roads.append(self.roadBuilder.createSimpleCurve(1, np.pi/4, True, curvature = 0.2))
        # roads.append(pyodrx.create_straight_road(2, 10))

        # roads[0].add_successor(pyodrx.ElementType.junction,1)

        # roads[1].add_predecessor(pyodrx.ElementType.road,0,pyodrx.ContactPoint.end)
        # # roads[1].add_predecessor(pyodrx.ElementType.road,0,pyodrx.ContactPoint.start)
        # roads[1].add_successor(pyodrx.ElementType.road,2,pyodrx.ContactPoint.start)

        # roads[2].add_predecessor(pyodrx.ElementType.junction,1, pyodrx.ContactPoint.end)

        odrName = "test_connectionRoad"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        self.laneBuilder.addRightTurnLaneUS(roads[0], 3)
        # self.laneBuilder.addRightLaneUS(roads[1])

        odr.resetAndReadjust(byPredecessor=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        xmlPath = f"output/test-RightLane.xodr"
        odr.write_xml(xmlPath)

    def test_DifferentLaneConfigurations(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        connectionRoad = self.straightRoadBuilder.createWithDifferentLanes(
            1, 10, n_lanes_left=2, n_lanes_right=2)
        roads.append(connectionRoad)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=2))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)

        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.end)
        roads[1].addExtendedSuccessor(roads[2], 0, pyodrx.ContactPoint.start)

        roads[2].addExtendedPredecessor(roads[1], 0, pyodrx.ContactPoint.end)

        self.laneBuilder.createLanesForConnectionRoad(connectionRoad, roads[0],
                                                      roads[2])

        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        xmlPath = f"output/test_DifferentLaneConfigurations.xodr"
        odr.write_xml(xmlPath)

    def test_addMedianIslandsToAllSections(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        self.laneBuilder.addMedianIslandsToAllSections(
            roads[0], self.configuration.get('default_lane_width'))
        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        xmlPath = f"output/test_addMedianIslandsToAllSections.xodr"
        odr.write_xml(xmlPath)

    def test_addMedianIslandsTo3Sections(self):

        road = self.straightRoadBuilder.create(1,
                                               n_lanes_left=1,
                                               n_lanes_right=1,
                                               length=20,
                                               force3Section=False)

        try:
            self.laneBuilder.addMedianIslandsTo2Of3Sections(
                road, 20, skipEndpoint=pyodrx.ContactPoint.start, width=3)
            assert False
        except:
            assert True

        road = self.straightRoadBuilder.create(1,
                                               n_lanes_left=1,
                                               n_lanes_right=1,
                                               length=20,
                                               force3Section=True)
        self.laneBuilder.addMedianIslandsTo2Of3Sections(
            road, 20, skipEndpoint=pyodrx.ContactPoint.start, width=3)

        assert len(road.lanes.lanesections[0].leftlanes) == 1
        assert len(road.lanes.lanesections[0].rightlanes) == 1
        assert len(road.lanes.lanesections[1].leftlanes) == 2
        assert len(road.lanes.lanesections[1].rightlanes) == 2
        assert len(road.lanes.lanesections[2].leftlanes) == 2
        assert len(road.lanes.lanesections[2].rightlanes) == 2

        road = self.straightRoadBuilder.create(1,
                                               n_lanes_left=1,
                                               n_lanes_right=1,
                                               length=20,
                                               force3Section=True)
        self.laneBuilder.addMedianIslandsTo2Of3Sections(
            road, 20, skipEndpoint=pyodrx.ContactPoint.end, width=3)

        assert len(road.lanes.lanesections[0].leftlanes) == 2
        assert len(road.lanes.lanesections[0].rightlanes) == 2
        assert len(road.lanes.lanesections[1].leftlanes) == 2
        assert len(road.lanes.lanesections[1].rightlanes) == 2
        assert len(road.lanes.lanesections[2].leftlanes) == 1
        assert len(road.lanes.lanesections[2].rightlanes) == 1

        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, [road], [])

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        xmlPath = f"output/test_addMedianIslandsTo3Sections.xodr"
        odr.write_xml(xmlPath)