/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.util;

import java.io.PrintStream;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestFailure;
import junit.framework.TestResult;
import junit.textui.ResultPrinter;

/**
 * Default result printer implementation for running tests in batch mode.
 *
 * @author Michael Bouschen
 */
public class BatchResultPrinter extends ResultPrinter {
  private static final DecimalFormat THREE_DIGITS_FORMATTER = new DecimalFormat("000");

  /** The stream to delegate the output. */
  private ConsoleFileOutput consoleFileOutput;

  /** The time elapsed to run a test suite. */
  private long runtime;

  /**
   * @param consoleFileOutput console file output
   */
  public BatchResultPrinter(ConsoleFileOutput consoleFileOutput) {
    this(new PrintStream(consoleFileOutput));
    this.consoleFileOutput = consoleFileOutput;
  }

  /**
   * @param writer the writer
   */
  public BatchResultPrinter(PrintStream writer) {
    super(writer);
  }

  /** Called in case of a test error. */
  @Override
  public void addError(Test test, Throwable t) {
    getWriter().print("   ERROR");
  }

  /** Called in case of a test failure. */
  @Override
  public void addFailure(Test test, AssertionFailedError t) {
    getWriter().print("   FAILURE");
  }

  /** Called when a test case is finished. */
  @Override
  public void endTest(Test test) {
    getWriter().println();
  }

  /** Called when a test case is started. */
  @Override
  public void startTest(Test test) {
    String testName;
    if (test instanceof TestCase) {
      testName = getClassBaseName(test) + "." + ((TestCase) test).getName();
    } else {
      testName = test.toString();
    }
    getWriter().print("RUN " + testName + '\t');
    getWriter().flush();
  }

  /**
   * @see ResultPrinter#elapsedTimeAsString(long)
   */
  @Override
  protected String elapsedTimeAsString(long runTime) {
    return THREE_DIGITS_FORMATTER.format((double) runTime / 1000);
  }

  /** */
  @Override
  protected void printHeader(long runTime) {
    this.runtime = runTime;
    getWriter().println("Description: " + System.getProperty("jdo.tck.description"));
    getWriter().println("Time: " + elapsedTimeAsString(runTime));
  }

  /** */
  @Override
  protected void printFooter(TestResult result) {
    String message = null;
    if (this.consoleFileOutput != null) {
      message = getResultMessage(result, this.consoleFileOutput);
      String directory = this.consoleFileOutput.getDirectory();
      ResultSummary.appendTCKResultMessage(directory, message);
      ResultSummary.save(directory, result);
    } else {
      message = getResultMessage(result);
    }

    if (!result.wasSuccessful()) {
      getWriter().println("FAILURES!!!");
      printErrorSummary(result);
    }

    getWriter().println(message);
    getWriter().println("Excluded tests: " + System.getProperty("jdo.tck.exclude"));
  }

  // helper method

  /**
   * Returns the result message for the given result instance and the given console file output
   * instance.
   *
   * @param result the result instance
   * @param consoleFileOutput the console file output instance
   * @return the result message
   */
  private String getResultMessage(TestResult result, ConsoleFileOutput consoleFileOutput) {
    String message = this.consoleFileOutput.getFileName() + ':';
    message += System.getProperty("line.separator") + "    ";
    message += getResultMessage(result);
    return message;
  }

  /**
   * Returns the result message for the given result instance.
   *
   * @param result the result instance
   * @return the result message
   */
  private String getResultMessage(TestResult result) {
    boolean success = result.wasSuccessful();
    String message = success ? "OK " : "** ";
    message +=
        "Tests run: "
            + THREE_DIGITS_FORMATTER.format(result.runCount())
            + ", Time: "
            + elapsedTimeAsString(this.runtime)
            + " seconds.";
    if (!success) {
      message += " Failures: " + result.failureCount() + ", Errors: " + result.errorCount();
    }
    return message;
  }

  /**
   * @return Name of the class of the given object without package prefix
   */
  private String getClassBaseName(Object obj) {
    if (obj == null) return null;
    String className = obj.getClass().getName();
    int index = className.lastIndexOf('.');
    if (index != -1) {
      className = className.substring(index + 1);
    }
    return className;
  }

  private void printErrorSummary(TestResult result) {
    Object[] array = getSortedArrayOfErrorSummaryEntries(result);
    if (array.length > 0) {
      getWriter().println("Error summary:");
      for (Object o : array) {
        getWriter().println(o);
      }
    }
  }

  private static Object[] getSortedArrayOfErrorSummaryEntries(TestResult result) {
    Map<String, ErrorSummaryEntry> map = new HashMap<>();
    for (Enumeration<TestFailure> e = result.errors(); e.hasMoreElements(); ) {
      TestFailure testFailure = e.nextElement();
      Throwable t = testFailure.thrownException();
      String message = getRootCause(t).toString();
      ErrorSummaryEntry errorSummaryEntry = map.get(message);
      if (errorSummaryEntry == null) {
        errorSummaryEntry = new ErrorSummaryEntry(t);
        map.put(message, errorSummaryEntry);
      }
      errorSummaryEntry.count++;
    }

    Object[] array = map.values().toArray();
    Arrays.sort(array);
    return array;
  }

  private static Throwable getRootCause(Throwable t) {
    while (t.getCause() != null) {
      t = t.getCause();
    }
    return t;
  }

  private static class ErrorSummaryEntry implements Comparable<ErrorSummaryEntry> {
    private int count = 0;
    private final Throwable t;

    private ErrorSummaryEntry(Throwable t) {
      this.t = t;
    }

    public boolean equals(Object o) {
      return compareTo((ErrorSummaryEntry) o) == 0;
    }

    public int hashCode() {
      return this.count;
    }

    public int compareTo(ErrorSummaryEntry o) {
      int result = this.count - o.count;
      if (result == 0) {
        String message1 = getRootCause().toString();
        String message2 = o.getRootCause().toString();
        result = message1.compareTo(message2);
      }
      return result;
    }

    public String toString() {
      StringBuilder buffer = new StringBuilder(THREE_DIGITS_FORMATTER.format(count));
      buffer.append(" error");
      if (this.count != 1) {
        buffer.append("s: ");
      } else {
        buffer.append(":  ");
      }
      buffer.append(getRootCause());
      return buffer.toString();
    }

    private Throwable getRootCause() {
      return BatchResultPrinter.getRootCause(this.t);
    }
  }
}
