/*
 * Copyright 2012-present Facebook, Inc.
 *
 * Licensed 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 com.facebook.buck.junit;

import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;

/**
 * Result of an individual test method in JUnit. Similar to {@link Result}, except that it always
 * corresponds to exactly one test method.
 */
final class TestResult {

  private static final String ENCODING = "UTF-8";

  final String testClassName;
  final String testMethodName;
  final long runTime;
  final /* @Nullable */ Failure failure;
  final /* @Nullable */ String stdOut;
  final /* @Nullable */ String stdErr;

  public TestResult(String testClassName,
      String testMethodName,
      long runTime,
      Failure failure,
      /* @Nullable */ String stdOut,
      /* @Nullable */ String stdErr) {
    this.testClassName = testClassName;
    this.testMethodName = testMethodName;
    this.runTime = runTime;
    this.failure = failure;
    this.stdOut = stdOut;
    this.stdErr = stdErr;
  }

  public boolean isSuccess() {
    return failure == null;
  }

  /**
   * Creates RunListener that will prepare individual result for each test
   * and store it to results list afterwards.
   */
  static RunListener createSingleTestResultRunListener(final List<TestResult> results) {
    return new RunListener() {

      private PrintStream originalOut, originalErr, stdOutStream, stdErrStream;
      private ByteArrayOutputStream rawStdOutBytes, rawStdErrBytes;
      private Result result;
      private RunListener resultListener;

      @Override
      public void testStarted(Description description) throws Exception {
        // Create an intermediate stdout/stderr to capture any debugging statements (usually in the
        // form of System.out.println) the developer is using to debug the test.
        originalOut = System.out;
        originalErr = System.err;
        rawStdOutBytes = new ByteArrayOutputStream();
        rawStdErrBytes = new ByteArrayOutputStream();
        stdOutStream = new PrintStream(
            rawStdOutBytes, true /* autoFlush */, ENCODING);
        stdErrStream = new PrintStream(
            rawStdErrBytes, true /* autoFlush */, ENCODING);
        System.setOut(stdOutStream);
        System.setErr(stdErrStream);

        // Prepare single-test result.
        result = new Result();
        resultListener = result.createListener();
        resultListener.testRunStarted(description);
        resultListener.testStarted(description);
      }

      @Override
      public void testFinished(Description description) throws Exception {
        // Shutdown single-test result.
        resultListener.testFinished(description);
        resultListener.testRunFinished(result);
        resultListener = null;

        // Restore the original stdout/stderr.
        System.setOut(originalOut);
        System.setErr(originalErr);

        // Get the stdout/stderr written during the test as strings.
        stdOutStream.flush();
        stdErrStream.flush();

        int numFailures = result.getFailureCount();
        String className = description.getClassName();
        String methodName = description.getMethodName();
        // In practice, I have seen one case of a test having more than one failure:
        // com.xtremelabs.robolectric.shadows.H2DatabaseTest#shouldUseH2DatabaseMap() had 2 failures.
        // However, I am not sure what to make of it, so we let it through.
        if (numFailures < 0) {
          throw new IllegalStateException(String.format(
              "Unexpected number of failures while testing %s#%s(): %d (%s)",
              className,
              methodName,
              numFailures,
              result.getFailures()));
        }
        Failure failure = numFailures == 0 ? null : result.getFailures().get(0);

        String stdOut = rawStdOutBytes.size() == 0 ? null : rawStdOutBytes.toString(ENCODING);
        String stdErr = rawStdErrBytes.size() == 0 ? null : rawStdErrBytes.toString(ENCODING);

        results.add(new TestResult(className,
            methodName,
            result.getRunTime(),
            failure,
            stdOut,
            stdErr));
      }

      @Override
      public void testAssumptionFailure(Failure failure) {
        if (resultListener != null) {
          resultListener.testAssumptionFailure(failure);
        }
      }

      @Override
      public void testFailure(Failure failure) throws Exception {
        if (resultListener != null) {
          resultListener.testFailure(failure);
        }
      }

      @Override
      public void testIgnored(Description description) throws Exception {
        if (resultListener != null) {
          resultListener.testIgnored(description);
        }
      }
    };
  }
}
