/* 
 * File:   HighwaysParserTest.cpp
 * Author: jtorres
 *
 * Created on Nov 1, 2017, 11:59:27 PM
 */

#include <stdlib.h>
#include <iostream>
#include "HighwaysParser.h"
#include "network.h"

using namespace std;

/*
 * Simple C++ Test Suite
 */
char * createBuffer()
{
    char * buffer = "2\n"
    "32 0 2\n"
    "1210831 1 5 S 0.9 8\n" 
    "1210832  0.0 0 ML_1\n"
    "1210833  0.0 0 ML_2\n"
    "1210834  0.0 0 ML_3\n"
    "1210835  0.0 0 ML_4\n"
    "1210836  0.0 0 PASSAGE\n"
    "1210837  0.0 0 DEMAND\n"
    "1210838  0.0 0 QUEUE\n"
    "1210839  0.0 0 RAMP_OFF\n"
    "1210845 2 5 S 1.49 9 \n"
    "1210846  0.0 0 ML_1\n"
    "1210847  0.0 0 ML_2\n"
    "1210848  0.0 0 ML_3\n"
    "1210849  0.0 0 ML_4\n"
    "1210850  0.0 0 RAMP_ON\n"
    "1210851  0.0 0 PASSAGE\n"
    "1210853  0.0 0 DEMAND\n"
    "1210854  0.0 0 QUEUE\n"
    "1210855  0.0 0 RAMP_OFF\n"
    "74 0 1\n"
    "1204203 2 5 N 1.26 13\n" 
    "1204205  0.0 0 RAMP_ON\n"
    "1204206  0.0 0 QUEUE\n"
    "1204207  0.0 0 DEMAND\n"
    "1204208  0.0 0 PASSAGE\n"
    "1204210  0.0 0 RAMP_OFF\n"
    "1204212  0.0 0 ML_1\n"
    "1204213  0.0 0 ML_2\n"
    "1204214  0.0 0 ML_3\n"
    "1204215  0.0 0 ML_4\n"
    "1204217  0.0 0 OS_1\n"
    "1204218  0.0 0 OS_2\n"
    "1204219  0.0 0 OS_3\n"
    "1204220  0.0 0 OS_4\n";
    return buffer;
}

void testParseLines() {
    char* highwaysData;
    HighwaysParser highwaysParser(createBuffer());
    vector<FEP_LINE *> lines = highwaysParser.lines;
    vector<STATION *> stations = highwaysParser.stations;
    
    // test number of lines
    int expectedNumLines = 2;
    int actualNumLines = lines.size();
    if (expectedNumLines != actualNumLines) {
        cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect number of lines" << endl;
    }
    
    // test line nums
    int expectedLineNums[2] = { 32, 74 };
    int actualLineNums[2] = { lines.at(0)->lineNum, lines.at(1)->lineNum };
    for(int i = 0; i < 2; i++)
    {
        if(expectedLineNums[i] != actualLineNums[i])
        {
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect line_id (LineNum)" << endl;
        }
    }
    
    // test lds id vector
    long expectedLDS[2] = { 1210831, 1210845 };
    long actualLDS[2] = { lines.at(0)->lds.at(0), lines.at(0)->lds.at(1) };
    for(int i = 0; i < 2; i++)
    {
        if(expectedLDS[i] != actualLDS[i])
        {
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect lds" << endl;
        }
    }
    
    // test lds index vector
    long expectedLDSIndex[2] = { 0, 1 };
    long actualLDSIndex[2] = { lines.at(0)->ldsIndex.at(0), lines.at(0)->ldsIndex.at(1) };
    for(int i = 0; i < 2; i++)
    {
        if(expectedLDSIndex[i] != actualLDSIndex[i])
        {
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect lds index" << endl;
        }
    }
    
    // test number of stations
    int expectedNumStations = 3;
    int actualNumStations = stations.size();
    
    if(expectedNumStations != actualNumStations)
    {
        cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect number of stations" << endl;
    }
    
    // test drop number
    int expectedDropNums[3] = { 1, 2, 2 };
    int actualDropNums[3] = { stations.at(0)->drop, stations.at(1)->drop, stations.at(2)->drop };
    for(int i = 0; i < 3; i++)
    {
        if(expectedDropNums[i] != actualDropNums[i])
        {
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect drop number" << endl;
        }
    }
    
    // test station lds numbers
    long expectedLDSNums[3] = { 1210831, 1210845, 1204203 };
    long actualLDSNums[3] = { stations.at(0)->lds, stations.at(1)->lds, stations.at(2)->lds };
    for(int i = 0; i < 3; i++)
    {
        if(expectedLDSNums[i] != actualLDSNums[i])
        {
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect station drop number" << endl;
        }
    }
    
    // test station line nums
    short expectedStnLineNums[3] = {32, 32, 74};
    short actualStnLineNums[3] = {stations.at(0)->line_num, stations.at(1)->line_num, stations.at(2)->line_num};
    for(int i = 0; i < 3; i++)
    {
        if(expectedStnLineNums[i] != actualStnLineNums[i])
        {
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect station line number" << endl;
        }
    }
    
    // test number of loops
    int expectedNumberOfLoops = 30;
    int actualNumberOfLoops = stations.at(0)->loops.size() + stations.at(1)->loops.size() + stations.at(2)->loops.size();
    
    if(expectedNumberOfLoops != actualNumberOfLoops)
    {
        cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect number of loops" << endl;
    }
    
    // test loops
    vector<LOOP *> loopsOne = stations.at(0)->loops;
    
    // test loopIDS
    long expectedLoopIDS[8] = { 1210832, 1210833, 1210834, 1210835, 
            1210836, 1210837, 1210838, 1210839 };
    long actualLoopIDS[8] = { loopsOne.at(0)->loopID, loopsOne.at(1)->loopID, 
            loopsOne.at(2)->loopID, loopsOne.at(3)->loopID, 
            loopsOne.at(4)->loopID, loopsOne.at(5)->loopID,
            loopsOne.at(6)->loopID, loopsOne.at(7)->loopID };
    for(int i = 0; i < 8; i++)
    {
        if(expectedLoopIDS[i] != actualLoopIDS[i])
        {
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect loop IDS" << endl;
        }
    }
    
    // test loop occ
    float expectedOCC[8] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
    float actualOCC[8] = { loopsOne.at(0)->occ, loopsOne.at(1)->occ, 
            loopsOne.at(2)->occ, loopsOne.at(3)->occ, loopsOne.at(4)->occ, 
            loopsOne.at(5)->occ, loopsOne.at(6)->occ, loopsOne.at(7)->occ };
    for(int i = 0; i < 8; i++)
    {
        if(expectedOCC[i] != actualOCC[i])
        {
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect loop IDS" << endl;
        }
    }
    
    // test loop locations
    char * expectedLocs[8] = {"ML_1", "ML_2", "ML_3", "ML_4", "PASSAGE", "DEMAND",
            "QUEUE", "RAMP_OFF"};
    char * actualLocs[8] = { loopsOne.at(0)->loop_loc, loopsOne.at(1)->loop_loc,
            loopsOne.at(2)->loop_loc, loopsOne.at(3)->loop_loc, loopsOne.at(4)->loop_loc,
            loopsOne.at(5)->loop_loc, loopsOne.at(6)->loop_loc, loopsOne.at(7)->loop_loc };

    for(int i = 0; i < 8; i++)
    {
        if(strcmp(expectedLocs[i], actualLocs[i]) != 0)
        {
            cout << "EXPECTED: " << expectedLocs[i] << endl;
            cout << "ACTUAL: " << actualLocs[i] << endl;
            cout << "%TEST_FAILED% time=0 testname=testParseLines (HighwaysParserTest) message=incorrect loop locs" << endl;
        }
    }
}

int main(int argc, char** argv) {
    cout << "%SUITE_STARTING% HighwaysParserTest" << endl;
    cout << "%SUITE_STARTED%" << endl;

    cout << "%TEST_STARTED% testParseLines (HighwaysParserTest)" << endl;
    testParseLines();
    cout << "%TEST_FINISHED% time=0 testParseLines (HighwaysParserTest)" << endl;

    cout << "%SUITE_FINISHED% time=0" << endl;

    return (EXIT_SUCCESS);
}

