/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hadoop.cli;

import org.apache.hadoop.cli.util.*;
import org.apache.hadoop.cli.util.CommandExecutor.Result;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeys;
import org.apache.hadoop.util.Shell;
import org.apache.hadoop.util.StringUtils;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.util.ArrayList;

/**
 * Tests for the Command Line Interface (CLI)
 */
public class CLITestHelper {
  private static final Logger LOG =
      LoggerFactory.getLogger(CLITestHelper.class.getName());
  
  // In this mode, it runs the command and compares the actual output
  // with the expected output  
  public static final String TESTMODE_TEST = "test"; // Run the tests
  
  // If it is set to nocompare, run the command and do not compare.
  // This can be useful populate the testConfig.xml file the first time
  // a new command is added
  public static final String TESTMODE_NOCOMPARE = "nocompare";
  public static final String TEST_CACHE_DATA_DIR =
    System.getProperty("test.cache.data", "build/test/cache");
  
  //By default, run the tests. The other mode is to run the commands and not
  // compare the output
  protected String testMode = TESTMODE_TEST;
  
  // Storage for tests read in from the config file
  protected ArrayList<CLITestData> testsFromConfigFile = null;
  protected ArrayList<ComparatorData> testComparators = null;
  protected String thisTestCaseName = null;
  protected ComparatorData comparatorData = null;
  protected Configuration conf = null;
  protected String clitestDataDir = null;
  protected String username = null;
  /**
   * Read the test config file - testConf.xml
   */
  protected void readTestConfigFile() {
    String testConfigFile = getTestFile();
    if (testsFromConfigFile == null) {
      boolean success = false;
      testConfigFile = TEST_CACHE_DATA_DIR + File.separator + testConfigFile;
      try {
        SAXParser p = (SAXParserFactory.newInstance()).newSAXParser();
        p.parse(testConfigFile, getConfigParser());
        success = true;
      } catch (Exception e) {
        LOG.info("File: " + testConfigFile + " not found");
        success = false;
      }
      assertTrue("Error reading test config file", success);
    }
  }

  /**
   * Method decides what is a proper configuration file parser for this type
   * of CLI tests.
   * Ancestors need to override the implementation if a parser with additional
   * features is needed. Also, such ancestor has to provide its own
   * TestConfigParser implementation
   * @return an instance of TestConfigFileParser class
   */
  protected TestConfigFileParser getConfigParser () {
    return new TestConfigFileParser();
  }

  protected String getTestFile() {
    return "";
  }
  
  /*
   * Setup
   */
  public void setUp() throws Exception {
    // Read the testConfig.xml file
    readTestConfigFile();
    
    conf = new Configuration();
    conf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION, 
                    true);

    clitestDataDir = new File(TEST_CACHE_DATA_DIR).
    toURI().toString().replace(' ', '+');
  }
  
  /**
   * Tear down
   */
  public void tearDown() throws Exception {
    displayResults();
  }
  
  /**
   * Expand the commands from the test config xml file
   * @param cmd
   * @return String expanded command
   */
  protected String expandCommand(final String cmd) {
    String expCmd = cmd;
    expCmd = expCmd.replaceAll("CLITEST_DATA", clitestDataDir);
    expCmd = expCmd.replaceAll("USERNAME", username);
    
    return expCmd;
  }
  
  /**
   * Display the summarized results
   */
  private void displayResults() {
    LOG.info("Detailed results:");
    LOG.info("----------------------------------\n");
    
    for (int i = 0; i < testsFromConfigFile.size(); i++) {
      CLITestData td = testsFromConfigFile.get(i);
      
      boolean testResult = td.getTestResult();
      
      // Display the details only if there is a failure
      if (!testResult) {
        LOG.info("-------------------------------------------");
        LOG.info("                    Test ID: [" + (i + 1) + "]");
        LOG.info("           Test Description: [" + td.getTestDesc() + "]");
        LOG.info("");

        ArrayList<CLICommand> testCommands = td.getTestCommands();
        for (CLICommand cmd : testCommands) {
          LOG.info("              Test Commands: [" + 
                   expandCommand(cmd.getCmd()) + "]");
        }

        LOG.info("");
        ArrayList<CLICommand> cleanupCommands = td.getCleanupCommands();
        for (CLICommand cmd : cleanupCommands) {
          LOG.info("           Cleanup Commands: [" +
                   expandCommand(cmd.getCmd()) + "]");
        }

        LOG.info("");
        ArrayList<ComparatorData> compdata = td.getComparatorData();
        for (ComparatorData cd : compdata) {
          boolean resultBoolean = cd.getTestResult();
          LOG.info("                 Comparator: [" + 
                   cd.getComparatorType() + "]");
          LOG.info("         Comparision result:   [" + 
                   (resultBoolean ? "pass" : "fail") + "]");
          LOG.info("            Expected output:   [" + 
                   expandCommand(cd.getExpectedOutput()) + "]");
          LOG.info("              Actual output:   [" + 
                   cd.getActualOutput() + "]");
        }
        LOG.info("");
      }
    }
    
    LOG.info("Summary results:");
    LOG.info("----------------------------------\n");
    
    boolean overallResults = true;
    int totalPass = 0;
    int totalFail = 0;
    int totalComparators = 0;
    for (int i = 0; i < testsFromConfigFile.size(); i++) {
      CLITestData td = testsFromConfigFile.get(i);
      totalComparators += 
    	  testsFromConfigFile.get(i).getComparatorData().size();
      boolean resultBoolean = td.getTestResult();
      if (resultBoolean) {
        totalPass ++;
      } else {
        totalFail ++;
      }
      overallResults &= resultBoolean;
    }
    
    
    LOG.info("               Testing mode: " + testMode);
    LOG.info("");
    LOG.info("             Overall result: " + 
    		(overallResults ? "+++ PASS +++" : "--- FAIL ---"));
    if ((totalPass + totalFail) == 0) {
      LOG.info("               # Tests pass: " + 0);
      LOG.info("               # Tests fail: " + 0);
    }
    else 
    {
      LOG.info("               # Tests pass: " + totalPass +
          " (" + (100 * totalPass / (totalPass + totalFail)) + "%)");
      LOG.info("               # Tests fail: " + totalFail + 
          " (" + (100 * totalFail / (totalPass + totalFail)) + "%)");
    }
    
    LOG.info("         # Validations done: " + totalComparators + 
    		" (each test may do multiple validations)");
    
    LOG.info("");
    LOG.info("Failing tests:");
    LOG.info("--------------");
    int i = 0;
    boolean foundTests = false;
    for (i = 0; i < testsFromConfigFile.size(); i++) {
      boolean resultBoolean = testsFromConfigFile.get(i).getTestResult();
      if (!resultBoolean) {
        LOG.info((i + 1) + ": " + 
        		testsFromConfigFile.get(i).getTestDesc());
        foundTests = true;
      }
    }
    if (!foundTests) {
    	LOG.info("NONE");
    }
    
    foundTests = false;
    LOG.info("");
    LOG.info("Passing tests:");
    LOG.info("--------------");
    for (i = 0; i < testsFromConfigFile.size(); i++) {
      boolean resultBoolean = testsFromConfigFile.get(i).getTestResult();
      if (resultBoolean) {
        LOG.info((i + 1) + ": " + 
        		testsFromConfigFile.get(i).getTestDesc());
        foundTests = true;
      }
    }
    if (!foundTests) {
    	LOG.info("NONE");
    }

    assertTrue("One of the tests failed. " +
    		"See the Detailed results to identify " +
    		"the command that failed", overallResults);
    
  }
  
  /**
   * Compare the actual output with the expected output
   * @param compdata
   * @return
   */
  private boolean compareTestOutput(ComparatorData compdata, Result cmdResult) {
    // Compare the output based on the comparator
    String comparatorType = compdata.getComparatorType();
    Class<?> comparatorClass = null;
    
    // If testMode is "test", then run the command and compare the output
    // If testMode is "nocompare", then run the command and dump the output.
    // Do not compare
    
    boolean compareOutput = false;
    
    if (testMode.equals(TESTMODE_TEST)) {
      try {
    	// Initialize the comparator class and run its compare method
        comparatorClass = Class.forName("org.apache.hadoop.cli.util." + 
          comparatorType);
        ComparatorBase comp = (ComparatorBase) comparatorClass.newInstance();
        compareOutput = comp.compare(cmdResult.getCommandOutput(), 
          expandCommand(compdata.getExpectedOutput()));
      } catch (Exception e) {
        LOG.info("Error in instantiating the comparator" + e);
      }
    }
    
    return compareOutput;
  }

  private boolean compareTextExitCode(ComparatorData compdata,
      Result cmdResult) {
    return compdata.getExitCode() == cmdResult.getExitCode();
  }
  
  /***********************************
   ************* TESTS RUNNER
   *********************************/
  
  public void testAll() {
    assertTrue("Number of tests has to be greater then zero",
      testsFromConfigFile.size() > 0);
    LOG.info("TestAll");
    // Run the tests defined in the testConf.xml config file.
    for (int index = 0; index < testsFromConfigFile.size(); index++) {
      
      CLITestData testdata = testsFromConfigFile.get(index);
   
      // Execute the test commands
      ArrayList<CLICommand> testCommands = testdata.getTestCommands();
      Result cmdResult = null;
      for (CLICommand cmd : testCommands) {
      try {
        cmdResult = execute(cmd);
      } catch (Exception e) {
        fail(StringUtils.stringifyException(e));
      }
      }
      
      boolean overallTCResult = true;
      // Run comparators
      ArrayList<ComparatorData> compdata = testdata.getComparatorData();
      for (ComparatorData cd : compdata) {
        final String comptype = cd.getComparatorType();
        
        boolean compareOutput = false;
        boolean compareExitCode = false;
        
        if (! comptype.equalsIgnoreCase("none")) {
          compareOutput = compareTestOutput(cd, cmdResult);
          if (cd.getExitCode() == -1) {
            // No need to check exit code if not specified
            compareExitCode = true;
          } else {
            compareExitCode = compareTextExitCode(cd, cmdResult);
          }
          overallTCResult &= (compareOutput & compareExitCode);
        }
        
        cd.setExitCode(cmdResult.getExitCode());
        cd.setActualOutput(cmdResult.getCommandOutput());
        cd.setTestResult(compareOutput);
      }
      testdata.setTestResult(overallTCResult);
      
      // Execute the cleanup commands
      ArrayList<CLICommand> cleanupCommands = testdata.getCleanupCommands();
      for (CLICommand cmd : cleanupCommands) {
      try { 
        execute(cmd);
      } catch (Exception e) {
        fail(StringUtils.stringifyException(e));
      }
      }
    }
  }

  /**
   * this method has to be overridden by an ancestor
   */
  protected CommandExecutor.Result execute(CLICommand cmd) throws Exception {
    throw new Exception("Unknown type of test command:"+ cmd.getType());
  }
  
  /*
   * Parser class for the test config xml file
   */
  class TestConfigFileParser extends DefaultHandler {
    String charString = null;
    CLITestData td = null;
    ArrayList<CLICommand> testCommands = null;
    ArrayList<CLICommand> cleanupCommands = null;
    boolean runOnWindows = true;
    
    @Override
    public void startDocument() throws SAXException {
      testsFromConfigFile = new ArrayList<CLITestData>();
    }
    
    @Override
    public void startElement(String uri, 
    		String localName, 
    		String qName, 
    		Attributes attributes) throws SAXException {
      if (qName.equals("test")) {
        td = new CLITestData();
      } else if (qName.equals("test-commands")) {
        testCommands = new ArrayList<CLICommand>();
      } else if (qName.equals("cleanup-commands")) {
        cleanupCommands = new ArrayList<CLICommand>();
      } else if (qName.equals("comparators")) {
        testComparators = new ArrayList<ComparatorData>();
      } else if (qName.equals("comparator")) {
        comparatorData = new ComparatorData();
        comparatorData.setExitCode(-1);
      }
      charString = "";
    }
    
    @Override
    public void endElement(String uri, String localName,String qName)
        throws SAXException {
      if (qName.equals("description")) {
        td.setTestDesc(charString);
      } else if (qName.equals("windows")) {
          runOnWindows = Boolean.parseBoolean(charString);
      } else if (qName.equals("test-commands")) {
        td.setTestCommands(testCommands);
        testCommands = null;
      } else if (qName.equals("cleanup-commands")) {
        td.setCleanupCommands(cleanupCommands);
        cleanupCommands = null;
      } else if (qName.equals("command")) {
        if (testCommands != null) {
          testCommands.add(new CLITestCmd(charString, new CLICommandFS()));
        } else if (cleanupCommands != null) {
          cleanupCommands.add(new CLITestCmd(charString, new CLICommandFS()));
        }
      } else if (qName.equals("comparators")) {
        td.setComparatorData(testComparators);
      } else if (qName.equals("comparator")) {
        testComparators.add(comparatorData);
      } else if (qName.equals("type")) {
        comparatorData.setComparatorType(charString);
      } else if (qName.equals("expected-output")) {
        comparatorData.setExpectedOutput(charString);
      } else if (qName.equals("expected-exit-code")) {
        comparatorData.setExitCode(Integer.valueOf(charString));
      } else if (qName.equals("test")) {
        if (!Shell.WINDOWS || runOnWindows) {
          testsFromConfigFile.add(td);
        }
        td = null;
        runOnWindows = true;
      } else if (qName.equals("mode")) {
        testMode = charString;
        if (!testMode.equals(TESTMODE_NOCOMPARE) &&
            !testMode.equals(TESTMODE_TEST)) {
          testMode = TESTMODE_TEST;
        }
      }
    }
    
    @Override
    public void characters(char[] ch, 
    		int start, 
    		int length) throws SAXException {
      String s = new String(ch, start, length);
      charString += s;
    }
  }
}
