package archive;

import atmsdriver.ConsoleTrafficDriver;
import atmsdriver.model.Highways;
import java.io.FileInputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import tmcsim.common.SimulationException;

/** "Super Old"
 * ATMS Driver reads the current simulation traffic conditions from the
 * EXCHANGE.XML file and constructs the Highway Network status info in the
 * format required by the FEP. It then sends this XML data over a socket to the
 * FEP Simulator.
 *
 * @author John A. Torres
 * @version 09/10/2017
 */
public class ATMSDriver implements Runnable
{

    /**
     * ATMSDriver Error logger.
     */
    private static Logger ATMSDriverLogger = Logger.getLogger("atmsdriver");

    /**
     * Properties object for the CADClient class.
     */
    private Properties ATMSDriverProperties;

    /**
     * Enumeration containing properties name values. See ATMSDriver class
     * description for more information.
     *
     * @author John Torres
     * @see ATMSDriver
     */
    private static enum PROPERTIES
    {
        HIGHWAYS_MAP_FILE_NAME("HighwaysMapFileName"),
        EXCHANGE_FILE_NAME("ExchangeFileName"),
        FEP_WRITER_HOST("FEPWriterHost"),
        FEP_WRITER_PORT("FEPWriterPort");

        public String name;

        private PROPERTIES(String n)
        {
            name = n;
        }
    }

    /**
     * Highways in traffic network
     */
    final private Highways highways;

    /**
     * Sleep Time (30 seconds). *
     */
    private static final int SLEEP_TIME = 30000;

    /**
     * Exchange Reader
     */
    private ExchangeReader exchangeReader;

    @Override
    public void run()
    {
        // Check for packets and update the simulator
        while (true)
        {
            // Flush the input file
            ExchangeInfo exInfo = exchangeReader.parse(ATMSDriverProperties
                    .getProperty(PROPERTIES.EXCHANGE_FILE_NAME.name));

            try
            {
                highways.writeToFEP();
            } catch (SimulationException ex)
            {
                System.out.println("Skipping writeToFEP...");
            }
            // Update if exchangeInfo is recieved
            if (exInfo != null)
            {
                // TODO: handle this condition
                Logger.getLogger("ATMSDriver").log(Level.INFO, "exInfo is not null");
            }

            // Wait for FEP Sim to process the data we just sent
            try
            {
                Thread.sleep(SLEEP_TIME);
            } catch (InterruptedException ie)
            {
                ie.printStackTrace();
            }
        }
    }

    public ATMSDriver(String propertiesFile)
    {
        // verify properties file
        if (!verifyProperties(propertiesFile))
        {
            System.exit(0);
        }
        // create the highways model
        highways = new Highways(
                ATMSDriverProperties.getProperty(
                        PROPERTIES.HIGHWAYS_MAP_FILE_NAME.name),
                ATMSDriverProperties.getProperty(PROPERTIES.FEP_WRITER_HOST.name),
                Integer.parseInt(ATMSDriverProperties.getProperty(
                                PROPERTIES.FEP_WRITER_PORT.name)));
        // create the exchange reader
        exchangeReader = new ExchangeReader();
    }

    /**
     * Verifies that the properties file has all necessary properties.
     *
     * @param propertiesFile
     * @return
     */
    private boolean verifyProperties(String propertiesFile)
    {
        // Load the properties file.
        try
        {
            ATMSDriverProperties = new Properties();
            ATMSDriverProperties.load(new FileInputStream(propertiesFile));
        } catch (Exception e)
        {
            ATMSDriverLogger.logp(Level.SEVERE, "ATMSDriver",
                    "Constructor", "Exception in reading properties file.", e);
        }

        return true;
    }

    /**
     * Runs the ATMS Driver.
     */
    public static void main(String[] args)
    {
        try
        {
            if (System.getProperty("ATMSDRIVER_PROPERTIES") != null)
            {
                // Create and run the ATMSDriver thread
                ATMSDriver atmsDriver = new ATMSDriver(System.getProperty("ATMSDRIVER_PROPERTIES"));
                Thread ATMSDriverThread = new Thread(atmsDriver);
                ATMSDriverThread.start();

                // run the console driver, pass it the atmsDriver highways model
                ConsoleTrafficDriver driver = new ConsoleTrafficDriver(atmsDriver.highways);

            } else
            {
                throw new Exception("ATMSDRIVER_PROPERTIES system property not defined.");
            }
        } catch (Exception e)
        {
            ATMSDriverLogger.logp(Level.SEVERE, "ATMSDriver", "Main",
                    "Error occured initializing application", e);
            System.exit(-1);
        }
    }
}
