/*
 * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.ejte.ccl.reporter;

/**
 * @Class : Reporter
   @Description : Main class used for Uniform reporting of results
   @Author : Ramesh Mandava
   @Last Modified : Initial Creation by Ramesh Mandava after taking input from
    Jeanfrancois and other Team members
   @Last Modified : By Ramesh on 1/20/2002 , Added code to use new testIdVector and
        testCaseIdVector for  preserving order of entry of them and now <tests>
        element is added around multiple tests
   @Last Modified : By Ramesh on 4/5/2002, Taken care of machine name unavailability
        under J2EE. And allowed having . in the path of result file

 *
 */


import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Date;
import java.util.Calendar;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;



public class Reporter extends Thread implements Serializable {

    /* FIELDS */


    private static Reporter reporterInstance = null;

    private String resultFile="default.xml";

    private FileOutputStream fout;
    private static String ws_home="sqe-pe";
    transient public PrintWriter out = new PrintWriter(System.out);
    private boolean hasBeenPrinted = false;
    /** testSuiteHash is a Hashtable holding info about different testsuites. */
    private static Hashtable testSuiteHash = new Hashtable();


    /**
    This method is used for setting the TestSuite Info
     */

    public void setTestSuite( String id, String name, String description )
    {

        TestSuite myTestSuite =  (TestSuite)testSuiteHash.get( id.trim() );
        if ( myTestSuite == null )
        {
            myTestSuite = new TestSuite( id, name,description);
            testSuiteHash.put( id.trim(), myTestSuite );
        }
    }

    /**
    This method is used for setting the TestSuite Info
     */
    public void setTestSuite( String id, String name)
    {
        TestSuite myTestSuite =  (TestSuite)testSuiteHash.get( id.trim() );
        if ( myTestSuite == null )
        {
            myTestSuite = new TestSuite( id.trim(), name);
            testSuiteHash.put( id.trim(), myTestSuite );
        }
    }

    /**
    This method is used for setting the TestSuite Info
     */
    public void setTestSuite( String id)
    {
        System.err.println("setTestSuite with id -> " + id );
        TestSuite myTestSuite =  (TestSuite)testSuiteHash.get( id.trim() );
        if ( myTestSuite == null )
        {
            myTestSuite = new TestSuite( id.trim());
            testSuiteHash.put( id.trim(), myTestSuite );
        }
    }

    /**
    After setting Test Suite info. suing setTestSuite, We need to use this addTest method
      for adding information about particular Test. We need to  pass both TestSuiteId and
      TestId  along with othe info of Test
     */
    public void addTest( String testSuiteId,  String testId, String testName, String testDescription )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:addTest might have called without setTestSuite. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id -> " + testSuiteId.trim() );
            return;
        }

        Test myTest = new Test( testId, testName, testDescription );
        myTestSuite.addTest( myTest );
    }

    /**
    After setting Test Suite info. suing setTestSuite, We need to use this addTest method
      for adding information about particular Test. We need to  pass both TestSuiteId and
      TestId  along with othe info of Test
     */
    public void addTest( String testSuiteId,  String testId, String testName )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:addTest might have called without setTestSuite. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id -> " + testSuiteId.trim() );
            return;
        }

        Test myTest = new Test( testId, testName );
        myTestSuite.addTest( myTest );
    }

    /**
    After using setthing Test Suite info. We need to use this addTest method
      for adding information about particular Test. We need to  pass both TestSuiteId and
      TestId
     */
    public void addTest( String testSuiteId,  String testId )
    {
        System.out.println("addTest with testSuiteId:: testId -> " + testSuiteId + "::" + testId );
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:addTest might have called without setTestSuite. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id -> " + testSuiteId.trim() );
            return;
        }

        Test myTest = new Test( testId );
        myTestSuite.addTest( myTest );
    }


    /**
        After adding a Test using addTest , We need to use this setTestStatus method
      for setting Test status(pass/fail) information about particular Test. We need to  pass both TestSuiteId and TestId  al
ong with expected and actual result. This is optional as in some case
     only TestCases will have status
     */
    public void setTestStatus ( String testSuiteId, String testId, String status, String expected, String actual )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );


        if ( myTestSuite== null )
        {
            System.err.println("ERROR:setTestStatus might have called without setTestSuite. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id -> " + testSuiteId.trim() );
            return;
        }

        Test myTest = (Test)myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:setTestStatus might have called without addTest. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id::Test Id -> " + testSuiteId.trim() + "::" + testId.trim() );
            return;
        }
        myTest.setStatus( status);
        myTest.setExpected( expected);
        myTest.setActual( actual);

    }

    /**
    After adding a Test using addTest , We need to use this setTestStatus method
      for setting Test status(pass/fail) information about particular Test. We need to  pass both TestSuiteId and TestId  along with status information. This is optional as in some case
     only TestCases will have status
     */
    public void setTestStatus ( String testSuiteId, String testId, String status, String statusDescription )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );


        if ( myTestSuite== null )
        {
            System.err.println("ERROR:setTestStatus might have called without setTestSuite. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id -> " + testSuiteId.trim() );
            return;
        }

        Test myTest = (Test)myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:setTestStatus might have called without addTest. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id::Test Id -> " + testSuiteId.trim() + "::" + testId.trim() );
            return;
        }
        myTest.setStatus( status);
        myTest.setStatusDescription( statusDescription);

    }

    /**
    After adding a Test using addTest , We need to use this setTestStatus method
      for setting Test status(pass/fail) information about particular Test. We need to  pass both TestSuiteId and TestId  along with status information. This is optional as in some case
     only TestCases will have status
     */
    public void setTestStatus ( String testSuiteId, String testId, String status )
    {
        System.out.println("setTestStatus testSuiteId::testId::status -> " + testSuiteId + "::" + testId + "::" + status );
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:setTestStatus might have called without setTestSuite. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id -> " + testSuiteId.trim() );
            return;
        }

        Test myTest =(Test) myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:setTestStatus might have called without addTest. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id::Test Id -> " + testSuiteId.trim() + "::" + testId.trim() );
            return;
        }
        myTest.setStatus( status);
    }

    /**
    After adding a Test using addTest, We need to use this addTestCase method
      for adding information about particular TestCase corresponding to that Test. We need to  pass TestSuiteId, TestId and TestCaseId along with othe info of TestCase
     */
    public void addTestCase( String testSuiteId,  String testId , String testCaseId)
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:addTestCase might have called without setTestSuite. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id -> " + testSuiteId.trim() );
            return;
        }
        Test myTest = (Test)myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:addTestCase might have called without addTest. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id::Test Id -> " + testSuiteId.trim() + "::" + testId.trim() );
            return;
        }

        TestCase myTestCase = new TestCase( testCaseId.trim() );
        myTest.addTestCase ( myTestCase );
    }

    /**
    After adding a Test using addTest, We need to use this addTestCase method
      for adding information about particular TestCase corresponding to that Test. We need to  pass TestSuiteId, TestId and TestCaseId along with othe info of TestCase
     */
    public void addTestCase( String testSuiteId,  String testId , String testCaseId, String testCaseName )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:addTestCase might have called without setTestSuite. PENDING : Shall we throw Exception?");
            return;
        }
        Test myTest = (Test)myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:addTestCase might have called without addTest. PENDING : Shall we throw Exception?");
            System.err.println("Given TestSuite Id::Test Id -> " + testSuiteId.trim() + "::" + testId.trim() );
            return;
        }

        TestCase myTestCase = new TestCase( testCaseId.trim(), testCaseName );
        myTest.addTestCase ( myTestCase );
    }

    /**
    After adding a Test using addTest, We need to use this addTestCase method
      for adding information about particular TestCase corresponding to that Test. We need to  pass TestSuiteId, TestId and TestCaseId along with othe info of TestCase
     */
    public void addTestCase( String testSuiteId,  String testId , String testCaseId, String testCaseName , String testCaseDescription )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:addTestCase might have called without setTestSuite. PENDING : Shall we throw Exception?");
            return;
        }
        Test myTest = (Test)myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:addTestCase might have called without addTest. PENDING : Shall we throw Exception?");
            return;
        }

        TestCase myTestCase = new TestCase( testCaseId.trim(), testCaseName, testCaseDescription );
        myTest.addTestCase ( myTestCase );
    }



    /**
        After adding a TestCase using addTestCase , We need to use this setTestCaseStatus method
      for setting TestCase status(pass/fail) information about particular TestCase. We need to  pass TestSuiteId, TestId and
 TestCaseId  along with status information. We pass expected and actual information along with pass/fail here
     */
    public void setTestCaseStatus ( String testSuiteId, String testId, String testCaseId,  String status, String expected, String actual )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without setTestSuite. PENDING : Shall we throwException?");
            return;
        }

        Test myTest = (Test)myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without addTest. PENDING : Shall we throw Exception?");
            return;
        }
        TestCase myTestCase =(TestCase) myTest.getTestCaseHash().get( testCaseId.trim() );
        if ( myTestCase == null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without addTestCase. PENDING : Shall we throwException?");
            return;
        }
        myTestCase.setStatus( status);
        myTestCase.setExpected( expected);
        myTestCase.setActual( actual);

    }


    /**
    After adding a TestCase using addTestCase , We need to use this setTestCaseStatus method
      for setting TestCase status(pass/fail) information about particular TestCase. We need to  pass TestSuiteId, TestId and TestCaseId  along with status information.
     Each TestCase will have status
     */
    public void setTestCaseStatus ( String testSuiteId, String testId, String testCaseId,  String status, String statusDescription )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without setTestSuite. PENDING : Shall we throw Exception?");
            return;
        }

        Test myTest = (Test)myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without addTest. PENDING : Shall we throw Exception?");
            return;
        }
        TestCase myTestCase =(TestCase) myTest.getTestCaseHash().get( testCaseId.trim() );
        if ( myTestCase == null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without addTestCase. PENDING : Shall we throw Exception?");
            return;
        }
        myTestCase.setStatus( status);
        myTestCase.setStatusDescription( statusDescription);

    }


    /**
    After adding a TestCase using addTestCase , We need to use this setTestCaseStatus method
      for setting TestCase status(pass/fail) information about particular TestCase. We need to  pass TestSuiteId, TestId and TestCaseId  along with status information.
     only TestCases will have status
     */
    public void setTestCaseStatus ( String testSuiteId, String testId, String testCaseId,  String status )
    {
        TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId.trim() );
        if ( myTestSuite== null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without setTestSuite. PENDING : Shall we throw Exception?");
            return;
        }

        Test myTest =(Test) myTestSuite.getTestHash().get( testId.trim() );
        if ( myTest == null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without addTest. PENDING : Shall we throw Exception?");
            return;
        }
        TestCase myTestCase = (TestCase)myTest.getTestCaseHash().get( testCaseId.trim() );
        if ( myTestCase == null )
        {
            System.err.println("ERROR:setTestCaseStatus might have called without addTestCase. PENDING : Shall we throw Exception?");
            return;
        }
        myTestCase.setStatus( status);

    }


    /**
     * Change done on 7/10/02 by Deepa Singh
     * Now Reporter will by default create results file in $EJTE_HOME if no results file is specified
     * So no need to pass the environment variable.
     * Reporter.getInstance should create test_results.xml at j2ee-test/
     *
     */


    public static Reporter getInstance( )
    {
        if ( reporterInstance == null )
        {
            //reporterInstance = new Reporter( );
            String rootpath=new File(".").getAbsolutePath();
            String ejte_home=rootpath.substring(0,rootpath.indexOf(ws_home));
            //ejte_home contains OS dependent path separator character without j2ee-test
            String outputDir=ejte_home+ws_home;
            reporterInstance = Reporter.getInstance( outputDir + File.separatorChar + "test_results.xml" );
        }

        return reporterInstance;

    }

    public static Reporter getInstance(String wshome)
    {
        if(reporterInstance == null)
        {
            String rootpath = (new File(".")).getAbsolutePath();
            String ejte_home = rootpath.substring(0, rootpath.indexOf(wshome));
            String outputDir = ejte_home + wshome;
            reporterInstance = new Reporter(outputDir + File.separatorChar + "test_results.xml");
        }
        return reporterInstance;
    }

    public static Reporter getInstance( String resultFilePath,boolean pathSpecified )
    {
        if ( reporterInstance == null )
        {
            reporterInstance = new Reporter(resultFilePath );

        }
        return reporterInstance;
    }

    //done only for the webtests.

    /*public static Reporter getInstance(String wshome) {
        if ( reporterInstance == null ) {
            String rootpath=new File(".").getAbsolutePath();
            //System.out.println("wshome from param is :"+wshome);
            //System.out.println("ROOT IS"+rootpath);
            String ejte_home=rootpath.substring(0,rootpath.indexOf(wshome));
            //ejte_home contains OS dependent path separator character without j2ee-test
            String outputDir=ejte_home+wshome;
            reporterInstance = new Reporter(outputDir + File.separatorChar + "test_results.xml");
            //reporterInstance = Reporter.getInstance( outputDir + File.separatorChar + "test_results.xml" );
            //reporterInstance = new Reporter(resultFilePath );

        }
        return reporterInstance;
    }*/


    public static Reporter getInstance( OutputStream outStream  )
    {
        if ( reporterInstance == null )
        {
            reporterInstance = new Reporter(outStream );

        }
        return reporterInstance;
    }

    public static Reporter getInstance( Writer writer  )
    {
        if ( reporterInstance == null )
        {

            reporterInstance = new Reporter(writer );

        }
        return reporterInstance;
    }
    /* CONSTRUCTORS */

    private Reporter( )
    {
        try{
            Runtime.getRuntime().addShutdownHook(this);
        } catch (java.lang.Exception ex){
            //System.out.println("WARNING: Reporter hook thread not created. No XML file will be produced.");
            System.out.println(ex.getMessage());
        }
    }

    private Reporter( String resultFilePath )
    {
        try{
            resultFile= resultFilePath;

            Runtime.getRuntime().addShutdownHook(this);
        } catch (java.lang.Exception ex){
            //System.out.println("WARNING: Reporter hook thread not created. No XML file will be produced.");
        }
    }



    private Reporter (OutputStream o) {
        this();
        out = new PrintWriter(o);
    }


    /* constructor for JSPs:
     * the "out" field in a JSP is a JSPWriter
     * which extends PrintWriter.    */

    private Reporter (Writer w) {
        this();
        out = new PrintWriter(w);
    }



    public void generateValidReport( )
    {

        //     System.out.println("REPORTER\t Inside generateValidReport");
        FileChannel rChannel = null;
        FileChannel wChannel = null;
        try
        {

            //Now flush all the TestSuite info

            //System.out.println("REPORTER\t generateValidReport.flushAll");
            flushAll();

            String oFileName =null;
            if ( resultFile.lastIndexOf(".") > 0 )
            {
                oFileName = resultFile.substring(0, resultFile.lastIndexOf(".") ) + "Valid.xml";
            }
            else
            {
                oFileName = resultFile + "Valid.xml";
            }
            wChannel = new FileOutputStream(oFileName).getChannel();

            String osName = System.getProperty("os.name");
            String osVersion = System.getProperty("os.version");
            String currentDate = (new Date()).toString();

            String extraXML = "<report> <date> " + currentDate + "</date><configuration>";
            extraXML += "<os>" + osName + osVersion + "</os>";
            extraXML += "<jdkVersion>" + System.getProperty("java.version") + "</jdkVersion>";

            String machineName = "unavailable";
            InputStream in = null;
            try {

                in  = Runtime.getRuntime().exec("uname -n").getInputStream();
                byte[] myBytes = new byte[200];
                in.read(myBytes);
                machineName = new String( myBytes ).trim();
            }
            catch ( Exception me ) {
            } finally {
                close(in);
            }

            extraXML += "<machineName>" + machineName + "</machineName>";
            extraXML += "</configuration> <testsuites>";

            wChannel.write(ByteBuffer.wrap(extraXML.getBytes()));

            rChannel = new FileInputStream(resultFile).getChannel();
            wChannel.transferFrom(rChannel, wChannel.position(), rChannel.size());
            wChannel.position(wChannel.position() + rChannel.size());

            wChannel.write(ByteBuffer.wrap("</testsuites>\n</report>\n".getBytes()));
            //System.out.println("REPORTER\t File validation complete");

        }
        catch ( Exception e )
        {
            System.out.println("ERROR : " + e );
        } finally {
            close(rChannel);
            close(wChannel);
        }
    }

    public void flushAll ( )
    {
        //    System.out.println("REPORTER\t inside flushAll") ;
        InputStream in = null;
        FileOutputStream foutput = null;
        try
        {
            Enumeration testSuiteEnum = testSuiteHash.keys();

            if ( resultFile.equals("default.xml") )
            {
                in  = Runtime.getRuntime().exec("uname -n").getInputStream();
                byte[] myBytes = new byte[200];
                in.read(myBytes);
                String myResultFile = "result_";
                String machineName = new String( myBytes ).trim();
                myResultFile += machineName;

                Calendar  myCalendar  = Calendar.getInstance();
                String month = new Integer( myCalendar.get ( Calendar.MONTH)).toString();
                String day = new Integer(myCalendar.get ( Calendar.DAY_OF_MONTH)).toString();
                String year = new Integer(myCalendar.get ( Calendar.YEAR)).toString();
                myResultFile += "_" + month + day + year + ".xml";
                resultFile= myResultFile;

            }

            foutput = new FileOutputStream( resultFile, true );
            while ( testSuiteEnum.hasMoreElements( ) )
            {
                String testSuiteId = (String) testSuiteEnum.nextElement();
                flush( testSuiteId, foutput );
            }

            System.out.println("in flushAll , creating new testSuiteHash");
            // Now take out the TestSuite info from memory
            testSuiteHash = new Hashtable();
        }
        catch ( Exception e )
        {
            System.err.println("ERROR: " + e );
        } finally {
            close(in);
            close(foutput);
        }


    }

    /**
     * This method prepares and output an XML representation of the Reporter class' content for the given testSuite.
     * @param testSuiteName the test suite's name.
     * @return returns true if the file is succesfully created
     */


    public boolean flush(String testSuiteId)
    {
        //System.out.println("REPORTER\t flush(testsuiteID");
        boolean returnVal=false;
        InputStream in = null;
        FileOutputStream foutput = null;
        try
        {

            if ( resultFile.equals("default.xml") )
            {
                in  = Runtime.getRuntime().exec("uname -n").getInputStream();
                byte[] myBytes = new byte[200];
                in.read(myBytes);
                String myResultFile = "result_";
                String machineName = new String( myBytes ).trim();
                myResultFile += machineName;

                Calendar  myCalendar  = Calendar.getInstance();
                String month = new Integer( myCalendar.get ( Calendar.MONTH)).toString();
                String day = new Integer(myCalendar.get ( Calendar.DAY_OF_MONTH)).toString();
                String year = new Integer(myCalendar.get ( Calendar.YEAR)).toString();
                myResultFile += "_" + month + day + year + ".xml";
                resultFile= myResultFile;

            }

            foutput = new FileOutputStream( resultFile, true );
            returnVal= flush( testSuiteId, foutput);
        }
        catch ( Exception e )
        {
            System.err.println("ERROR : " + e );
        } finally {
            close(in);
            close(foutput);
        }
        return returnVal;
    }

    /**
     * This method prepares and output an XML representation of the Reporter class' content for the given testSuite.
     * @param testSuiteName the test suite's name.
     * @param foutput the FileOutputStream in which we need to write.
     * @return returns true if the file is succesfully created
     */
    public boolean flush(String testSuiteId, FileOutputStream foutput){
        //System.out.println("REPORTER\t flush(testsuiteId,fout)");
        try{
            StringBuffer xmlRepresentation = new StringBuffer();

            /*
            xmlRepresentation.append("<?xml version=\"1.0\"?>\n");
            xmlRepresentation.append("<!DOCTYPE testsuite SYSTEM \"test_suite.dtd\">\n");

            xmlRepresentation.append("<!-- ID are defined as: test suite: test case : local id-->\n");
             */

            TestSuite myTestSuite = (TestSuite)testSuiteHash.get( testSuiteId );
            if ( myTestSuite == null )
            {
                System.err.println("ERROR: Information for TestSuite Id : " + testSuiteId + " doesn't exist");
                return false;
            }
            String testSuiteName = myTestSuite.getName();
            String testSuiteDescription = myTestSuite.getDescription();

            xmlRepresentation.append("<testsuite>\n" );
            xmlRepresentation.append("  <id> " + testSuiteId + " </id>\n");

            if (!testSuiteName.equals( ReporterConstants.NA ) )
            {
                xmlRepresentation.append("<name>" + testSuiteName.trim() + "</name>\n");
            }
            if (!testSuiteDescription.equals( ReporterConstants.NA ) )
            {
                xmlRepresentation.append("<description><![CDATA[" + testSuiteDescription + "]]></description>\n");
            }

            Hashtable testHash = myTestSuite.getTestHash( );

            Vector testIdVector = myTestSuite.getTestIdVector( );

            xmlRepresentation.append("<tests>\n");
            for ( int ti=0; ti< testIdVector.size(); ti++ )
            {

                String testId = (String)testIdVector.elementAt(ti );
                Test myTest = (Test)testHash.get( testId.trim() );
                String testName = myTest.getName();
                String testDescription = myTest.getDescription();
                String testStatus = myTest.getStatus();
                String testStatusDescription = myTest.getStatusDescription();

                String testExpected= myTest.getExpected( );
                String testActual= myTest.getActual( );

                xmlRepresentation.append("<test>\n");
                xmlRepresentation.append("<id>" + testId + "</id>\n");

                if (!testName.equals( ReporterConstants.NA ) )
                {
                    xmlRepresentation.append("<name>" + testName + "</name>\n");
                }

                if (!testDescription.equals( ReporterConstants.NA ) )
                {
                    xmlRepresentation.append("<description><![CDATA[" + testDescription + "]]></description>\n");
                }
                if (!testStatus.equals( ReporterConstants.OPTIONAL ) )
                {
                    if (!testStatusDescription.equals( ReporterConstants.OPTIONAL ) )
                    {
                        xmlRepresentation.append("<status value=\"" + testStatus + "\"><![CDATA[" + testStatusDescription + "]]></status>\n");
                    }
                    else if ( ( testExpected != null ) && ( testActual != null ) )
                    {
                        xmlRepresentation.append("<status value=\"" + testStatus + "\"> <expected><![CDATA[" + testExpected + "]]></expected><actual><![CDATA[" + testActual +   "]]></actual></status>\n");
                    }
                    else {
                        xmlRepresentation.append("<status value=\"" + testStatus + "\">" + "</status>\n");
                    }
                }

                Hashtable testCaseHash = myTest.getTestCaseHash();
                Vector testCaseIdVector = myTest.getTestCaseIdVector( );

                /*
        if ( testCaseIdVector.size( ) < 1 )
        {
            // This means there are no test cases and Test has the status info
            xmlRepresentation.append("</test>\n");

        }
                 */
                if ( testCaseIdVector.size() >= 1 )
                {
                    xmlRepresentation.append("<testcases>\n");

                    for ( int tc=0; tc< testCaseIdVector.size(); tc++ )
                    {
                        String testCaseId = (String)testCaseIdVector.elementAt( tc );
                        TestCase myTestCase = (TestCase)testCaseHash.get( testCaseId.trim() );

                        String testCaseName = myTestCase.getName();
                        String testCaseDescription = myTestCase.getDescription();
                        String testCaseStatus = myTestCase.getStatus();
                        String testCaseStatusDescription = myTestCase.getStatusDescription();
                        String testCaseExpected = myTestCase.getExpected();
                        String testCaseActual = myTestCase.getActual();

                        xmlRepresentation.append("<testcase>\n");
                        xmlRepresentation.append("<id> " + testCaseId + "</id>\n");
                        if (!testCaseName.equals( ReporterConstants.NA ) )
                        {
                            xmlRepresentation.append("<name>" + testCaseName + "</name>\n");
                        }

                        if (!testCaseDescription.equals( ReporterConstants.NA ) )
                        {
                            xmlRepresentation.append("<description><![CDATA[" + testCaseDescription + "]]></description>\n");
                        }
                        if (!testCaseStatusDescription.equals( ReporterConstants.NA ) )
                        {
                            xmlRepresentation.append("<status value=\"" + testCaseStatus + "\"><![CDATA[" + testCaseStatusDescription + "]]></status>\n");
                        }
                        else if ( ( testCaseExpected != null ) && ( testCaseActual != null ) )
                        {
                            xmlRepresentation.append("<status value=\"" + testCaseStatus + "\"> <expected><![CDATA[" + testCaseExpected + "]]></expected><actual><![CDATA[" + testCaseActual +   "]]></actual></status>\n");
                        }
                        else
                        {
                            xmlRepresentation.append("<status value=\"" + testCaseStatus + "\">" + "</status>\n");
                        }
                        xmlRepresentation.append("</testcase>\n");
                    }

                    xmlRepresentation.append("</testcases>\n");

                }

                xmlRepresentation.append("</test>\n");
            }

            xmlRepresentation.append("</tests>\n" );
            xmlRepresentation.append("</testsuite>\n" );
            boolean writeResult =  writeXMLFile(xmlRepresentation, foutput);
            // Now remove TestSuite from Hashtable: PENDING
            if ( writeResult==true )
            {
                // If we could write teh content properly then remove the TestSuite from Hashtable
                testSuiteHash.remove( testSuiteId.trim() );
            }
            return writeResult;
        } catch (java.lang.Exception ex){
            return false;
        }
    }

    private boolean writeXMLFile(StringBuffer xmlStringBuffer){
        PrintWriter writer = null;
        try{
            writer = new PrintWriter(new BufferedWriter(new FileWriter(resultFile)));
            writer.println( xmlStringBuffer.toString() );
            writer.flush();
        } catch(java.io.IOException ex){
            ex.printStackTrace();
            return false;
        } finally {
            close(writer);
        }
        return true;
    }

    private boolean writeXMLFile(StringBuffer xmlStringBuffer, FileOutputStream  fout){
        try{
            fout.write( xmlStringBuffer.toString().getBytes() );
            fout.flush( );
        } catch(java.io.IOException ex){
            ex.printStackTrace();
            return false;
        }
        return true;
    }

    public void run(){
        //System.out.println("REPORTER\t Inside run");
        generateValidReport();
    }

    private void close(InputStream in) {
        if (in != null) {
            try {
                in.close();
            } catch(IOException ioe) {
                // ignore
            }
        }
    }

    private void close(OutputStream out) {
        if (out != null) {
            try {
                out.close();
            } catch(IOException ioe) {
                // ignore
            }
        }
    }

    private void close(Writer writer) {
        if (writer != null) {
            try {
                writer.close();
            } catch(IOException ioe) {
                // ignore
            }
        }
    }

    private void close(FileChannel fileChannel) {
        if (fileChannel != null) {
            try {
                fileChannel.close();
            } catch(IOException ioe) {
                // ignore
            }
        }
    }
} // end class Reporter
