/*
 * Copyright (c) 2017, 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;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.io.*;

//public class SimpleReporterAdapter extends Thread implements Serializable {
public class SimpleReporterAdapter implements Serializable {
    private boolean debug=true;
    private String testSuiteDescription;
    private HashMap testCaseStatus;
    public static String PASS = "pass";
    public static String DID_NOT_RUN = "did_not_run";
    public static String FAIL = "fail";
    private String testSuiteName = "undefined";
    private String testSuiteID = null;
    private String ws_home="sqe-pe";
    private String outputDir=null;
    private Reporter reporter=null;
    private String resultFile="test_results";
    private boolean isFileSet=false;


    public SimpleReporterAdapter()  {
        testSuiteName = "undefined";
        testSuiteID = null;
        ws_home = "appserv-tests";
        outputDir = null;
        reporter = null;
        try {
            outputDir = null;
        }
        catch(Exception ex) { }
    }


    public SimpleReporterAdapter(String ws_root)     {
        testSuiteName = "undefined";
        testSuiteID = null;
        ws_home = "appserv-tests";
        outputDir = null;
        reporter = null;
        try {
            outputDir = null;
            ws_home = ws_root;
        }
        catch(Exception ex) { }
    }

    //used by webrunner
    public SimpleReporterAdapter(String resultFilePath,boolean isResultFileSet){
        try{
            this.isFileSet=true;
            this.resultFile=resultFilePath;
        }catch( Exception ex ){ }
    }



    public synchronized void addStatus(String s, String status)    {
        if( testSuiteName.compareTo("undefined") == 0 ) {
            int blankIndex = s.indexOf(" ");

            if(blankIndex!=-1){
                testSuiteName = s.substring(0, blankIndex);
            } else {
                testSuiteName = s;
            }
            testSuiteID = s + "ID";
        }
        if( testCaseStatus == null ){
            testCaseStatus = new HashMap(5);
        }

        int blankIndex = s.indexOf(" ");
        String key = s;
        if (blankIndex!=-1){
            key = s.substring(s.indexOf( " " ));
        }
        if(debug)
            System.out.println("Value of key is:"+key);

        if( !testCaseStatus.containsKey( key ) ){
            testCaseStatus.put( key , status.toLowerCase() );
        }
    }

    public void addDescription(String s)    {
        testSuiteDescription = s;
    }

    public void printStatus() {
        try{
            //Reporter reporter;
            Set keySets;
            Iterator keySetsIT;
            Properties p;

            if(testSuiteName.compareTo("undefined") == 0)
                testSuiteName = getTestSuiteName();
            String rootpath = (new File(".")).getAbsolutePath();
            String ejte_home = rootpath.substring(0, rootpath.indexOf(ws_home));
            outputDir = ejte_home + ws_home;
            reporter = Reporter.getInstance(ws_home);
            if(debug)
                System.out.println("Generating report at \t" + outputDir +
                        File.separatorChar + "test_results.xml");
            reporter.setTestSuite(testSuiteID, testSuiteName, testSuiteDescription);
            reporter.addTest(testSuiteID, testSuiteID, testSuiteName);
            keySets = testCaseStatus.keySet();
            keySetsIT = keySets.iterator();
            String tcName;

            int pass= 0;
            int fail = 0;
            int d_n_r = 0;
            String status;
            System.out.println("\n\n-----------------------------------------");
            while( keySetsIT.hasNext() ){
                tcName = keySetsIT.next().toString();
                status =  testCaseStatus.get( tcName ).toString();

                if (status.equalsIgnoreCase(PASS)){
                    pass++;
                } else if(status.equalsIgnoreCase(DID_NOT_RUN)){
                    d_n_r++;
                } else {
                    fail++;
                }

                System.out.println("-\t " + tcName + ": " + status.toUpperCase() + "\t-");
                reporter.addTestCase( testSuiteID, testSuiteID, tcName + "ID", tcName );
                reporter.setTestCaseStatus( testSuiteID, testSuiteID, tcName + "ID", status );
            }
            System.out.println("-----------------------------------------");
            System.out.println("Total PASS:\t" + pass);
            System.out.println("Total FAIL:\t" + fail);
            System.out.println("Total DID NOT RUN: " + d_n_r);
            System.out.println("-----------------------------------------");
            //reporter.flush(testSuiteID);
            reporter.generateValidReport();
            createConfirmationFile();
        }
        catch( Throwable ex )        {
            System.out.println( "Reporter exception occurred!" );
            if(debug)
                ex.printStackTrace();
        }
    }

    public void createConfirmationFile(){
        try{
            FileOutputStream fout = new FileOutputStream("RepRunConf.txt");
            String text = "Test has been reported";
            fout.write(text.getBytes());
            fout.close();
        } catch (Exception e){
            System.out.println("Exception while creating confirmation file!");
            if(debug)
                e.printStackTrace();
        }
    }


    public void printSummary(String s) {
        printStatus();
    }

    public void printSummary() {
        printStatus();
    }

    public void run() {
        printSummary();
        reporter.generateValidReport();
    }

    private String getTestSuiteName()    {
        String s = new File( "" ).getAbsolutePath();
        return s.substring(s.lastIndexOf(File.separator)+1, s.length());
    }

    public void clearStatus()    {
        testCaseStatus.clear();
        testSuiteName = "undefined";
    }

    /**
     *A dead function.
     * J2EE server security contraints don't allow use of exec
     */

    public Properties getEnvVars() throws Throwable {
        Process p = null;
        Properties envVars = new Properties();
        Runtime r = Runtime.getRuntime();
        String OS = System.getProperty("os.name").toLowerCase();
        // System.out.println(OS);
        if (OS.indexOf("windows 9") > -1) {
            p = r.exec( "command.com /c set" );
        }
        else if ( (OS.indexOf("nt") > -1) || (OS.indexOf("windows 2000") > -1) ) {
            p = r.exec( "cmd.exe /c set" );
        }
        else {
            p = r.exec( "env" );
        }
        BufferedReader br =
            new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while( (line = br.readLine()) != null ) {
            int idx = line.indexOf( '=' );
            String key = line.substring( 0, idx );
            String value = line.substring( idx+1 );
            envVars.setProperty( key, value );
            if(debug)
             System.out.println( key + " = " + value );
        }
        return envVars;
    }
}
