/*
 * 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.jdo.tck.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.io.Serializable;
import javax.jdo.JDOFatalException;
import junit.framework.TestResult;

/** A serializable class used to store test results in a file. */
public class ResultSummary implements Serializable {
  private static final long serialVersionUID = 1L;

  /** The name of the file to store a serialized instance of this class. */
  private static final String FILE_NAME_OF_RESULT_SUMMARY = "ResultSummary.ser";

  /** The name of the TCK result file. */
  private static final String RESULT_FILE_NAME = "TCK-results.txt";

  /* The number of all configurations. */
  private int nrOfTotalConfigurations = 0;

  /* The number of failed configurations. */
  private int nrOfFailedConfigurations = 0;

  /* The total number of tests. */
  private int totalTestCount = 0;

  /* The total number of failures. */
  private int totalFailureCount = 0;

  /* The total number of errors. */
  private int totalErrorCount = 0;

  /**
   * Deserializes an instance and prints that instance to {@link System#out} and the TCK result
   * file. Finally deletes the file of the serialized instance.
   *
   * @param args the first element contains the directory where the test result is stored.
   */
  public static void main(String[] args) {
    // print result summary

    String directory = args[0] + File.separator;
    ResultSummary resultSummary = ResultSummary.load(directory);
    String newLine = System.getProperty("line.separator");
    String resultMessage = resultSummary != null ? resultSummary.toString() : "No tests were run.";
    String message = "-------" + newLine + resultMessage;
    appendTCKResultMessage(directory, message);
    System.out.println(resultMessage);
    System.out.println("See file '" + directory + RESULT_FILE_NAME + "' for details.");

    // delete file
    String fileName = args[0] + File.separator + FILE_NAME_OF_RESULT_SUMMARY;
    File file = new File(fileName);
    file.delete();
  }

  /**
   * Appends the given message to the TCK result file in the given directory.
   *
   * @param directory the directory
   * @param message the message
   */
  static void appendTCKResultMessage(String directory, String message) {
    String fileName = directory + RESULT_FILE_NAME;
    try (PrintStream resultStream = new PrintStream(new FileOutputStream(fileName, true))) {
      resultStream.println(message);
    } catch (FileNotFoundException e) {
      throw new JDOFatalException("Cannot create file " + fileName, e);
    }
  }

  /**
   * Creates an instance for the given result object and serializes that instance to a file in the
   * geven directory.
   *
   * @param directory the directory
   * @param result the result object
   */
  static void save(String directory, TestResult result) {
    ResultSummary resultSummary = load(directory);
    if (resultSummary == null) {
      resultSummary = new ResultSummary();
    }
    resultSummary.increment(result);
    resultSummary.save(directory);
  }

  /**
   * Returns a deserialized instance stored in the given direcotry.
   *
   * @param directory the directory
   * @return the deserialized instance
   */
  private static ResultSummary load(String directory) {
    ResultSummary result;
    String fileName = directory + FILE_NAME_OF_RESULT_SUMMARY;
    try {
      try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
        result = (ResultSummary) ois.readObject();
      }
    } catch (FileNotFoundException e) {
      result = null;
    } catch (IOException | ClassNotFoundException e) {
      throw new JDOFatalException("Cannot deserialize result summary in file " + fileName, e);
    }
    return result;
  }

  /**
   * Increments fields of this instance based on the given result object.
   *
   * @param result the result object
   */
  private void increment(TestResult result) {
    this.nrOfTotalConfigurations++;
    this.totalTestCount += result.runCount();
    if (!result.wasSuccessful()) {
      this.nrOfFailedConfigurations++;
      this.totalFailureCount += result.failureCount();
      this.totalErrorCount += result.errorCount();
    }
  }

  /**
   * Serializes this instance to a file in the given directory.
   *
   * @param directory the directory
   */
  private void save(String directory) {
    String fileName = directory + FILE_NAME_OF_RESULT_SUMMARY;
    try {
      try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
        oos.writeObject(this);
      }
    } catch (FileNotFoundException e) {
      throw new JDOFatalException("Cannot create file " + fileName, e);
    } catch (IOException e) {
      throw new JDOFatalException("Cannot serialize result summary to file " + fileName, e);
    }
  }

  /**
   * @see Object#toString()
   */
  public String toString() {
    String newLine = System.getProperty("line.separator");
    StringBuilder result = new StringBuilder();
    result.append("Total tests run: ").append(totalTestCount).append(".");
    if (this.nrOfFailedConfigurations == 0) {
      result.append(newLine);
      result.append("All (").append(this.nrOfTotalConfigurations);
      result.append(") configurations passed.");
    } else {
      result.append(" Failures: ").append(totalFailureCount);
      result.append(", Errors: ").append(totalErrorCount).append(".");
      result.append(newLine);
      result.append(this.nrOfFailedConfigurations).append(" of ");
      result.append(this.nrOfTotalConfigurations);
      result.append(" configurations failed.");
    }
    return result.toString();
  }
}
