package tmcsim.cadsimulator;

import java.io.File;
import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;
import static org.mockito.Mockito.*;
import org.uispec4j.*;
import org.uispec4j.interception.WindowInterceptor;
import tmcsim.cadsimulator.managers.ParamicsSimulationManager;
import tmcsim.common.CADEnums;
import tmcsim.common.ScriptException;
import tmcsim.common.SimulationException;
import tmcsim.interfaces.CADClientInterface;
import tmcsim.interfaces.SimulationManagerInterface;

/**
 * Test of CADSimulator GUI
 *
 * @author jdalbey
 */
public class CADSimulatorGUITest extends UISpecTestCase
{

    static final String configData =
            "CADClientPort          = 4444 \n"
            + "CoordinatorRMIPort     = 4445 \n"
            + "CADRmiPort             = 4446 \n"
            + "UserInterface          = tmcsim.cadsimulator.viewer.CADSimulatorViewer\n"
            + "ParamicsProperties     = pconfig.txt\n"
            + "ATMSProperties         = empty.txt\n"
            + "MediaProperties        = empty.txt\n";

    public CADSimulatorGUITest(String testName)
    {
        super(testName);
    }

    @Override
    public void tearDown() throws java.io.IOException
    {
        File removeMe = new File("config.txt");
        removeMe.delete();
        removeMe = new File("pconfig.txt");
        removeMe.delete();
        removeMe = new File("empty.txt");
        removeMe.delete();
    }
    /**
     * Test of main method, of class CADSimulator.
     */
    CADSimulator app;

    public void testConstructor() throws SimulationException, RemoteException, ScriptException
    {
        System.out.println("CADSimulator constructor");
        CADSimulatorFixture.writeConfigData();
        CADSimulatorFixture.writedata("config.txt", configData);
        Window cadwindow = null;
//        try
//        {
//            app = new CADSimulator("config.txt");
//        } catch (Exception e)
//        {
//            fail("Couldn't launch CADSimulator" + e.getMessage());
//        }

        System.setProperty("CONFIG_DIR", "config/testConfig");
        if (System.getProperty("CONFIG_DIR") != null)
        {
            cadwindow = WindowInterceptor.run(new Trigger()
            {
                public void run()
                {
                    try
                    {
                        app = new CADSimulator(System.getProperty("CONFIG_DIR") + System.getProperty("file.separator") + "cad_simulator_config.properties");

                    } catch (Exception e)
                    {
                        fail("Couldn't launch CADSimulator" + e.getMessage());
                    }
                }
            });
        }
        else
        {
            fail("CONFIG_DIR system property not defined.");
        }

        System.out.println("Tests for text fields.");
        // Create a UISpec window from the CADSimulator's Viewer (gui)
//        cadwindow = new Window((CADSimulatorViewer) app.theViewer);
        assertTrue("Title bar incorrect", cadwindow.getTitle().startsWith("CAD Simulator revision:"));
        Panel mainPanel = cadwindow.getPanel("contentPane");
        TextBox txtStatus = mainPanel.getTextBox("simulationStatus");
        assertEquals("simulation status should say No Script", "No Script", txtStatus.getText().trim());
        TextBox terminals = mainPanel.getTextBox("termConnectedTF");
        assertEquals("should be 0 terminals", "0", terminals.getText().trim());
        assertEquals("mgr connected should be no", "No", mainPanel.getTextBox("managerConnectedTF").getText().trim());
        assertEquals("paramics connected should be no", "No", mainPanel.getTextBox("paramicsConnectedTF").getText().trim());
        assertEquals("initial time should be 0:00:00", "0:00:00", mainPanel.getTextBox("simulationClockLabel").getText().trim());

        CADClientInterface ci = mock(CADClientInterface.class);
        app.theCoordinator.registerForCallback(ci);
        assertEquals("should be 1 terminal", "1", terminals.getText().trim());
        app.theCoordinator.registerForCallback(ci);
        assertEquals("should be 2 terminals", "2", terminals.getText().trim());

        SimulationManagerInterface si = mock(SimulationManagerInterface.class);

        app.theCoordinator.registerForCallback(si);
        assertEquals("mgr connected should be yes", "Yes", mainPanel.getTextBox("managerConnectedTF").getText().trim());

        Logger cadSimLogger = Logger.getLogger("tmcsim.cadsimulator");
        cadSimLogger.logp(Level.INFO, "", "", "Sample Info Message.");

        System.out.println("Tests for message panes.");
        Panel infoPane = mainPanel.getPanel("infoMessagesPane");
        TextBox infoText = infoPane.getTextBox("infoMessagesTA");
        assertEquals("wrong info msg text", ". = Sample Info Message.", infoText.getText().trim());

        cadSimLogger.logp(Level.SEVERE, "", "", "Sample Error Message.");

        Panel errPane = mainPanel.getPanel("errorMessagesPane");
        TextBox errText = errPane.getTextBox("errorMessagesTA");
        assertEquals("wrong error msg text", ". = Sample Error Message.", errText.getText().trim());

        System.out.println("Tests for status changes.");
        app.theCoordinator.setParamicsStatus(CADEnums.PARAMICS_STATUS.CONNECTED);
        CADSimulatorFixture.pause(500);
        assertEquals("paramics connected should be yes", "Yes", mainPanel.getTextBox("paramicsConnectedTF").getText().trim());
        assertEquals("network id should be None", "None", mainPanel.getTextBox("networkLoadedTF").getText().trim());

//        app.theCoordinator.setScriptStatus(CADEnums.SCRIPT_STATUS.SCRIPT_RUNNING);
//        assertEquals("Running", mainPanel.getTextBox("simulationStatus").getText().trim());

        // Load a script file
        String autoloadScriptname = "scripts/one-incident.xml";
        app.theCoordinator.loadScriptFile(new File(autoloadScriptname));
        // The status should now say Ready
        assertEquals("sim status should be ready", "Ready", mainPanel.getTextBox("simulationStatus").getText().trim());

        app.theCoordinator.startSimulation();
        CADSimulatorFixture.pause(900);
        assertEquals("sim status should be running", "Running", mainPanel.getTextBox("simulationStatus").getText().trim());
        assertEquals("sim time should be 0:00:01", "0:00:01", mainPanel.getTextBox("simulationClockLabel").getText().trim());

        ParamicsSimulationManager psm = mock(ParamicsSimulationManager.class);
        when(psm.isConnected()).thenReturn(Boolean.TRUE);
        when(psm.getParamicsNetworkLoaded()).thenReturn(1); // provide the network ID to return
        app.theParamicsSimMgr = psm;
        // this will tell the model it has a new network ID
        app.theCoordinator.setParamicsStatus(CADEnums.PARAMICS_STATUS.LOADED);
        CADSimulatorFixture.pause(500);
        assertEquals("network id should be 1", "1", mainPanel.getTextBox("networkLoadedTF").getText().trim());
        //mainPanel.getMenu().getItem("Exit").click();
        boolean breakpoint = true;
    }
}
