package seng302.Mock;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import seng302.GPSCoordinate;
import seng302.Model.Leg;
import seng302.Model.Marker;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * Tests only work on the current version of mockXML/raceXML/raceTest.xml
 */
public class StreamedRaceTest {
    private StreamedCourseXMLReader streamedCourseXMLReader;
    private List<GPSCoordinate> boundary;

    @Before
    public void setup() {
        try {
            streamedCourseXMLReader = new StreamedCourseXMLReader("mockXML/raceXML/raceTest.xml", true);
            boundary = streamedCourseXMLReader.getBoundary();
        } catch (Exception | StreamedCourseXMLException e) {
            e.printStackTrace();
            //fail("Cannot find mockXML/raceXML/raceTest.xml in the resources folder");
        }
    }

    @Test
    public void testAllBoundaryPointsRead() {
        assertEquals(boundary.size(), 10);
    }

    @Test
    public void testBoundaryPointData() {
        // First point
        assertEquals(boundary.get(0).getLatitude(), -36.8325, 1e-6);
        assertEquals(boundary.get(0).getLongitude(), 174.8325, 1e-6);

        // Last point
        assertEquals(boundary.get(boundary.size() - 1).getLatitude(), -36.83417, 1e-6);
        assertEquals(boundary.get(boundary.size() - 1).getLongitude(), 174.84767, 1e-6);
    }

    @Test
    public void testMapEdges() {
        double maxLatitude = streamedCourseXMLReader.getMapBottomRight().getLatitude() - streamedCourseXMLReader.getPadding();
        double maxLongitude = streamedCourseXMLReader.getMapBottomRight().getLongitude() - streamedCourseXMLReader.getPadding();
        double minLatitude = streamedCourseXMLReader.getMapTopLeft().getLatitude() - streamedCourseXMLReader.getPadding();
        double minLongitude = streamedCourseXMLReader.getMapTopLeft().getLongitude() - streamedCourseXMLReader.getPadding();

        assertEquals(maxLatitude, -36.81033, 1e-6);
        assertEquals(maxLongitude, 174.88217, 1e-6);
        assertEquals(minLatitude, -36.83417, 1e-6);
        assertEquals(minLongitude, 174.81983, 1e-6);
    }

    @Test
    public void testRaceSettings() {

    }

    @Test
    public void correctLegSequence() {
        List<Leg> legs = streamedCourseXMLReader.getLegs();
        String[] expectedNames = {
                "StartLine",
                "M1",
                "M2",
                "Gate"
        };
        for(int i = 0; i < legs.size(); i++) {
            assertEquals(expectedNames[i], legs.get(i).getName());
        }
    }

    /**
     * raceTest.xml is not compliant with this test. Markers are positioned far out of bounds.
     */
    @Test
    @Ignore
    public void markersWithinRaceBoundaries() {
        GPSCoordinate topLeft = streamedCourseXMLReader.getMapTopLeft();
        GPSCoordinate bottomRight = streamedCourseXMLReader.getMapBottomRight();

        for(Marker compoundMark : streamedCourseXMLReader.getMarkers()) {
            GPSCoordinate centre = compoundMark.getAverageGPSCoordinate();
            assertTrue(centre.getLatitude() < bottomRight.getLatitude());
            assertTrue(centre.getLatitude() > topLeft.getLatitude());
            assertTrue(centre.getLongitude() > bottomRight.getLongitude());
            assertTrue(centre.getLongitude() < topLeft.getLongitude());
        }
    }
}
