package tmcsim.cadsimulator;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.rmi.RemoteException;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
import org.uispec4j.*;
import org.uispec4j.interception.WindowInterceptor;
import tmcsim.common.ScriptException;
import tmcsim.common.SimulationException;
import tmcsim.paramicscommunicator.ParamicsCommunicator;
import tmcsim.paramicscommunicator.gui.ParamicsCommunicatorGUI;
import tmcsim.simulationmanager.SimulationManager;

/**
 * System test (include CADSimulator) with emulated Paramics Modeler NO ATMS
 * server captures GUI display using UISpec4J.
 *
 * @author jdalbey
 */
public class SystemTest extends UISpecTestCase
{

    SimulationManager simMgrApp;
    CADSimulator engine;
//    ParamicsCommunicator paramicscomm;

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

    @Override
    protected void setUp() throws Exception
    {
        super.setUp();
    }

    /**
     * Test of run method, of class ParamicsCommunicator.
     */
    public void testRun() throws ScriptException, SimulationException, RemoteException
    {
        System.out.println("Invisible System Test");
        Window cadwindow = null;
        cadwindow = WindowInterceptor.run(new Trigger()
        {
            public void run()
            {
                try
                {
                    engine = new CADSimulator("config/testConfig/cad_simulator_config.properties");
                } catch (Exception e)
                {
                    fail("Couldn't launch CADSimulator");
                }
            }
        });

        // Check CAD Simulator appears with no script and nothing connected
        assertTrue("Title bar incorrect", cadwindow.getTitle().trim().startsWith("CAD Simulator"));
        Panel mainPanel = cadwindow.getPanel("contentPane");
        TextBox txtStatus = mainPanel.getTextBox("simulationStatus");
        assertEquals("No Script", txtStatus.getText());
        TextBox terms = mainPanel.getTextBox("termConnectedTF");
        assertEquals("0", terms.getText().trim());
        assertEquals("No", mainPanel.getTextBox("managerConnectedTF").getText().trim());
        assertEquals("network id should be None", "None", mainPanel.getTextBox("networkLoadedTF").getText().trim());

        ParamicsCommunicator pc = null;
        pc = new ParamicsCommunicator("config/testConfig/paramics_communicator_config.properties");
        ParamicsCommunicatorGUI theGUI = new ParamicsCommunicatorGUI();
        pc.setGUI(theGUI);
        // Note: Can't set visible ANY windows during UISpec test

        // expect pcomm to say "sleeping"

        Window simMgrWindow = null;
        simMgrWindow = WindowInterceptor.run(new Trigger()
        {
            public void run()
            {
                try
                {
                    simMgrApp = new SimulationManager("config/sim_manager_systest_config.properties");
                } catch (Exception ex)
                {
                    fail("Couldn't launch Simulation Manager");
                }
            }
        });

        // TODO: Check that the Sim Mgr GUI appears without a script loaded yet

        Panel contentPanel = simMgrWindow.getPanel("contentPane");
        TextBox txtSimStatus = contentPanel.getTextBox("simulationStatusText");
        assertEquals("No Script", txtSimStatus.getText());
        TextBox txtParamStatus = contentPanel.getTextBox("paramicsStatusInfoLabel");
        assertEquals("Unknown", txtParamStatus.getText());
        Button loadNetworkBtn = simMgrWindow.getButton("Load Network");
        assertFalse(loadNetworkBtn.isEnabled());

        Button paramicsBtn = simMgrWindow.getButton("Connect to Paramics");
        paramicsBtn.click();
        try
        {
            Thread.sleep(200);
        } catch (Exception ex)
        {
        }
        assertEquals("Disconnect from Paramics", paramicsBtn.getLabel());

        assertEquals("Connected", txtParamStatus.getText());
        pc.startReading();

        loadNetworkBtn.click();
        try
        {
            Thread.sleep(200);
        } catch (Exception ex)
        {
        }
        assertEquals("Sending Network ID", txtParamStatus.getText());
        System.out.println("Sending Network ID");
        assertFalse(loadNetworkBtn.isEnabled());
        String warmingXML = "<Paramics>\n"
                + "<Network_Status>WARMING</Network_Status>\n"
                + "<Network_ID>1</Network_ID>\n"
                + "</Paramics>";
        writedata("paramics_status.xml", warmingXML);
        try
        {
            Thread.sleep(2100);
        } catch (Exception ex)
        {
        }
        assertEquals("Warming Up", txtParamStatus.getText());
        System.out.println("Warming Up Passed");

        try
        {
            Thread.sleep(2100);
        } catch (Exception ex)
        {
        }
        String loadedXML = "<Paramics>\n"
                + "<Network_Status>LOADED</Network_Status>"
                + "<Network_ID>1</Network_ID>"
                + "</Paramics>";
        writedata("paramics_status.xml", loadedXML);
        try
        {
            Thread.sleep(2100);
        } catch (Exception ex)
        {
        }
        assertEquals("Network 1 Loaded", txtParamStatus.getText());
        assertEquals("network id should be 1", "1", mainPanel.getTextBox("networkLoadedTF").getText().trim());


        // Load a script file
        String autoloadScriptname = "scripts/system_test_script.xml";
        simMgrApp.loadScript(new File(autoloadScriptname));
        try
        {
            Thread.sleep(500);
        } catch (Exception ex)
        {
        }

        // The status should now say Ready
        assertEquals("Ready", txtSimStatus.getText());

        // Click "Start"
        simMgrWindow.getButton("Start").click();
        try
        {
            Thread.sleep(200);
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }
        assertEquals("Running", txtSimStatus.getText());
        System.out.println("Running Passed");
        try
        {
            Thread.sleep(9000);
        } catch (InterruptedException ex)
        {
        }
        simMgrWindow.getButton("Pause").click();
        try
        {
            Thread.sleep(3000);
        } catch (InterruptedException ex)
        {
        }
        simMgrWindow.getButton("Start").click();
        try
        {
            Thread.sleep(3000);
        } catch (InterruptedException ex)
        {
        }
        simMgrWindow.getButton("Pause").click();
        simMgrWindow.getMenuBar().getMenu("File").getSubMenu("Exit").click();
        System.out.println("Exiting.");
    }

    // Write the test data to a file
    public static void writedata(String filename, String data)
    {
        PrintWriter writer = null;
        try
        {
            writer = new PrintWriter(new FileWriter(filename));
            writer.println(data);
            writer.close();
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
}
