// Copyright 2017 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.android.desugar.runtime;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.android.desugar.runtime.ThrowableExtension.MimicDesugaringStrategy.SUPPRESSED_PREFIX;
import static com.google.devtools.build.android.desugar.runtime.ThrowableExtensionTestUtility.getTwrStrategyClassNameSpecifiedInSystemProperty;
import static com.google.devtools.build.android.desugar.runtime.ThrowableExtensionTestUtility.isNullStrategy;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import com.google.devtools.build.android.desugar.runtime.ThrowableExtension.MimicDesugaringStrategy;
import com.google.devtools.build.android.desugar.runtime.ThrowableExtension.NullDesugaringStrategy;
import com.google.devtools.build.android.desugar.runtime.ThrowableExtension.ReuseDesugaringStrategy;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.function.Consumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Test case for {@link ThrowableExtension} */
@RunWith(JUnit4.class)
public class ThrowableExtensionTest {

  /**
   * This test tests the behavior of closing resources via reflection. This is only enabled below
   * API 19. So, if the API level is 19 or above, this test will simply skip.
   */
  @Test
  public void testCloseResourceViaReflection() throws Throwable {
    class Resource extends AbstractResource {
      protected Resource(boolean exceptionOnClose) {
        super(exceptionOnClose);
      }

      public void close() throws Exception {
        super.internalClose();
      }
    }
    if (ThrowableExtension.API_LEVEL >= 19) {
      return;
    }
    {
      Resource r = new Resource(false);
      assertThat(r.isClosed()).isFalse();
      ThrowableExtension.closeResource(null, r);
      assertThat(r.isClosed()).isTrue();
    }
    {
      Resource r = new Resource(true);
      assertThat(r.isClosed()).isFalse();
      assertThrows(IOException.class, () -> ThrowableExtension.closeResource(null, r));
    }
    {
      Resource r = new Resource(false);
      assertThat(r.isClosed()).isFalse();
      ThrowableExtension.closeResource(new Exception(), r);
      assertThat(r.isClosed()).isTrue();
    }
    {
      Resource r = new Resource(true);
      assertThat(r.isClosed()).isFalse();
      assertThrows(Exception.class, () -> ThrowableExtension.closeResource(new Exception(), r));
    }
  }

  /**
   * Test the new method closeResources() in the runtime library.
   *
   * <p>The method is introduced to fix b/37167433.
   */
  @Test
  public void testCloseResource() throws Throwable {

    /**
     * A resource implementing the interface AutoCloseable. This interface is only available since
     * API 19.
     */
    class AutoCloseableResource extends AbstractResource implements AutoCloseable {

      protected AutoCloseableResource(boolean exceptionOnClose) {
        super(exceptionOnClose);
      }

      @Override
      public void close() throws Exception {
        internalClose();
      }
    }

    /** A resource implementing the interface Closeable. */
    class CloseableResource extends AbstractResource implements Closeable {

      protected CloseableResource(boolean exceptionOnClose) {
        super(exceptionOnClose);
      }

      @Override
      public void close() throws IOException {
        internalClose();
      }
    }

    {
      CloseableResource r = new CloseableResource(false);
      assertThat(r.isClosed()).isFalse();
      ThrowableExtension.closeResource(null, r);
      assertThat(r.isClosed()).isTrue();
    }
    {
      CloseableResource r = new CloseableResource(false);
      assertThat(r.isClosed()).isFalse();
      Exception suppressor = new Exception();
      ThrowableExtension.closeResource(suppressor, r);
      assertThat(r.isClosed()).isTrue();
      assertThat(ThrowableExtension.getSuppressed(suppressor)).isEmpty();
    }
    {
      CloseableResource r = new CloseableResource(true);
      assertThat(r.isClosed()).isFalse();
      assertThrows(IOException.class, () -> ThrowableExtension.closeResource(null, r));
      assertThat(r.isClosed()).isFalse();
    }
    {
      CloseableResource r = new CloseableResource(true);
      assertThat(r.isClosed()).isFalse();
      Exception suppressor = new Exception();
      assertThrows(Exception.class, () -> ThrowableExtension.closeResource(suppressor, r));
      assertThat(r.isClosed()).isFalse(); // Failed to close.
      if (!isNullStrategy()) {
        assertThat(ThrowableExtension.getSuppressed(suppressor)).hasLength(1);
        assertThat(ThrowableExtension.getSuppressed(suppressor)[0].getClass())
            .isEqualTo(IOException.class);
      }
    }
    {
      AutoCloseableResource r = new AutoCloseableResource(false);
      assertThat(r.isClosed()).isFalse();
      ThrowableExtension.closeResource(null, r);
      assertThat(r.isClosed()).isTrue();
    }
    {
      AutoCloseableResource r = new AutoCloseableResource(false);
      assertThat(r.isClosed()).isFalse();
      Exception suppressor = new Exception();
      ThrowableExtension.closeResource(suppressor, r);
      assertThat(r.isClosed()).isTrue();
      assertThat(ThrowableExtension.getSuppressed(suppressor)).isEmpty();
    }
    {
      AutoCloseableResource r = new AutoCloseableResource(true);
      assertThat(r.isClosed()).isFalse();
      assertThrows(IOException.class, () -> ThrowableExtension.closeResource(null, r));
      assertThat(r.isClosed()).isFalse();
    }
    {
      AutoCloseableResource r = new AutoCloseableResource(true);
      assertThat(r.isClosed()).isFalse();
      Exception suppressor = new Exception();
      assertThrows(Exception.class, () -> ThrowableExtension.closeResource(suppressor, r));
      assertThat(r.isClosed()).isFalse(); // Failed to close.
      if (!isNullStrategy()) {
        assertThat(ThrowableExtension.getSuppressed(suppressor)).hasLength(1);
        assertThat(ThrowableExtension.getSuppressed(suppressor)[0].getClass())
            .isEqualTo(IOException.class);
      }
      assertThat(r.isClosed()).isFalse();
    }
  }

  /**
   * LightweightStackTraceRecorder tracks the calls of various printStackTrace(*), and ensures that
   *
   * <p>suppressed exceptions are printed only once.
   */
  @Test
  public void testLightweightStackTraceRecorder() throws IOException {
    MimicDesugaringStrategy strategy = new MimicDesugaringStrategy();
    ExceptionForTest receiver = new ExceptionForTest(strategy);
    FileNotFoundException suppressed = new FileNotFoundException();
    strategy.addSuppressed(receiver, suppressed);

    String trace = printStackTraceStderrToString(() -> strategy.printStackTrace(receiver));
    assertThat(trace).contains(SUPPRESSED_PREFIX);
    assertThat(countOccurrences(trace, SUPPRESSED_PREFIX)).isEqualTo(1);
  }

  @Test
  public void testMimicDesugaringStrategy() throws IOException {
    MimicDesugaringStrategy strategy = new MimicDesugaringStrategy();
    IOException receiver = new IOException();
    FileNotFoundException suppressed = new FileNotFoundException();
    strategy.addSuppressed(receiver, suppressed);

    assertThat(
            printStackTracePrintStreamToString(
                stream -> strategy.printStackTrace(receiver, stream)))
        .contains(SUPPRESSED_PREFIX);

    assertThat(
            printStackTracePrintWriterToString(
                writer -> strategy.printStackTrace(receiver, writer)))
        .contains(SUPPRESSED_PREFIX);

    assertThat(printStackTraceStderrToString(() -> strategy.printStackTrace(receiver)))
        .contains(SUPPRESSED_PREFIX);
  }

  private void testThrowableExtensionWithMimicDesugaringStrategy() throws IOException {
    IOException receiver = new IOException();
    FileNotFoundException suppressed = new FileNotFoundException();
    ThrowableExtension.addSuppressed(receiver, suppressed);

    assertThat(
            printStackTracePrintStreamToString(
                stream -> ThrowableExtension.printStackTrace(receiver, stream)))
        .contains(SUPPRESSED_PREFIX);
    assertThat(
            printStackTracePrintWriterToString(
                writer -> ThrowableExtension.printStackTrace(receiver, writer)))
        .contains(SUPPRESSED_PREFIX);
    assertThat(printStackTraceStderrToString(() -> ThrowableExtension.printStackTrace(receiver)))
        .contains(SUPPRESSED_PREFIX);
  }

  private interface PrintStackTraceCaller {
    void printStackTrace();
  }

  private static String printStackTraceStderrToString(PrintStackTraceCaller caller)
      throws IOException {
    PrintStream err = System.err;
    try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
      PrintStream newErr = new PrintStream(stream);
      System.setErr(newErr);
      caller.printStackTrace();
      newErr.flush();
      return stream.toString();
    } finally {
      System.setErr(err);
    }
  }

  private static String printStackTracePrintStreamToString(Consumer<PrintStream> caller)
      throws IOException {
    try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
      PrintStream printStream = new PrintStream(stream);
      caller.accept(printStream);
      printStream.flush();
      return stream.toString();
    }
  }

  private static String printStackTracePrintWriterToString(Consumer<PrintWriter> caller)
      throws IOException {
    try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
      PrintWriter printWriter =
          new PrintWriter(new BufferedWriter(new OutputStreamWriter(stream, UTF_8)));
      caller.accept(printWriter);
      printWriter.flush();
      return stream.toString();
    }
  }

  @Test
  public void testNullDesugaringStrategy() throws IOException {
    NullDesugaringStrategy strategy = new NullDesugaringStrategy();
    IOException receiver = new IOException();
    FileNotFoundException suppressed = new FileNotFoundException();
    strategy.addSuppressed(receiver, suppressed);
    assertThat(strategy.getSuppressed(receiver)).isEmpty();

    strategy.addSuppressed(receiver, suppressed);
    assertThat(strategy.getSuppressed(receiver)).isEmpty();

    assertThat(printStackTracePrintStreamToString(stream -> receiver.printStackTrace(stream)))
        .isEqualTo(
            printStackTracePrintStreamToString(
                stream -> strategy.printStackTrace(receiver, stream)));

    assertThat(printStackTracePrintWriterToString(receiver::printStackTrace))
        .isEqualTo(
            printStackTracePrintWriterToString(
                writer -> strategy.printStackTrace(receiver, writer)));

    assertThat(printStackTraceStderrToString(receiver::printStackTrace))
        .isEqualTo(printStackTraceStderrToString(() -> strategy.printStackTrace(receiver)));
  }

  private void testThrowableExtensionWithNullDesugaringStrategy() throws IOException {
    IOException receiver = new IOException();
    FileNotFoundException suppressed = new FileNotFoundException();
    ThrowableExtension.addSuppressed(receiver, suppressed);
    assertThat(ThrowableExtension.getSuppressed(receiver)).isEmpty();

    ThrowableExtension.addSuppressed(receiver, suppressed);
    assertThat(ThrowableExtension.getSuppressed(receiver)).isEmpty();

    assertThat(printStackTracePrintStreamToString(stream -> receiver.printStackTrace(stream)))
        .isEqualTo(
            printStackTracePrintStreamToString(
                stream -> ThrowableExtension.printStackTrace(receiver, stream)));
    assertThat(printStackTracePrintWriterToString(receiver::printStackTrace))
        .isEqualTo(
            printStackTracePrintWriterToString(
                writer -> ThrowableExtension.printStackTrace(receiver, writer)));

    assertThat(printStackTraceStderrToString(receiver::printStackTrace))
        .isEqualTo(
            printStackTraceStderrToString(() -> ThrowableExtension.printStackTrace(receiver)));
  }

  @Test
  public void testReuseDesugaringStrategy() throws IOException {
    ReuseDesugaringStrategy strategy = new ReuseDesugaringStrategy();
    IOException receiver = new IOException();
    FileNotFoundException suppressed = new FileNotFoundException();
    strategy.addSuppressed(receiver, suppressed);
    assertThat(strategy.getSuppressed(receiver))
        .asList()
        .containsExactly((Object[]) receiver.getSuppressed());

    assertThat(printStackTracePrintStreamToString(stream -> receiver.printStackTrace(stream)))
        .isEqualTo(
            printStackTracePrintStreamToString(
                stream -> strategy.printStackTrace(receiver, stream)));

    assertThat(printStackTracePrintWriterToString(receiver::printStackTrace))
        .isEqualTo(
            printStackTracePrintWriterToString(
                writer -> strategy.printStackTrace(receiver, writer)));
    assertThat(printStackTraceStderrToString(receiver::printStackTrace))
        .isEqualTo(printStackTraceStderrToString(() -> strategy.printStackTrace(receiver)));
  }

  private void testThrowableExtensionWithReuseDesugaringStrategy() throws IOException {
    IOException receiver = new IOException();
    FileNotFoundException suppressed = new FileNotFoundException();
    ThrowableExtension.addSuppressed(receiver, suppressed);
    assertThat(ThrowableExtension.getSuppressed(receiver))
        .asList()
        .containsExactly((Object[]) receiver.getSuppressed());

    assertThat(printStackTracePrintStreamToString(receiver::printStackTrace))
        .isEqualTo(
            printStackTracePrintStreamToString(
                stream -> ThrowableExtension.printStackTrace(receiver, stream)));

    assertThat(printStackTracePrintWriterToString(receiver::printStackTrace))
        .isEqualTo(
            printStackTracePrintWriterToString(
                writer -> ThrowableExtension.printStackTrace(receiver, writer)));

    assertThat(printStackTraceStderrToString(receiver::printStackTrace))
        .isEqualTo(
            printStackTraceStderrToString(() -> ThrowableExtension.printStackTrace(receiver)));
  }

  /** This class */
  private static class ExceptionForTest extends Exception {

    private final MimicDesugaringStrategy strategy;

    public ExceptionForTest(MimicDesugaringStrategy strategy) {
      this.strategy = strategy;
    }

    @Override
    public void printStackTrace() {
      this.printStackTrace(System.err);
    }

    /**
     * This method should call this.printStackTrace(PrintWriter) directly. I deliberately change it
     * to strategy.printStackTrace(Throwable, PrintWriter) to simulate the behavior of Desguar, that
     * is, the direct call is intercepted and redirected to ThrowableExtension.
     */
    @Override
    public void printStackTrace(PrintStream s) {
      this.strategy.printStackTrace(
          this, new PrintWriter(new BufferedWriter(new OutputStreamWriter(s, UTF_8))));
    }
  }

  @Test
  public void testStrategySelection() throws ClassNotFoundException, IOException {
    String expectedStrategyClassName = getTwrStrategyClassNameSpecifiedInSystemProperty();
    assertThat(expectedStrategyClassName).isNotEmpty();
    assertThat(expectedStrategyClassName)
        .isEqualTo(ThrowableExtension.STRATEGY.getClass().getName());

    Class<?> expectedStrategyClass = Class.forName(expectedStrategyClassName);
    if (expectedStrategyClass.equals(ReuseDesugaringStrategy.class)) {
      testThrowableExtensionWithReuseDesugaringStrategy();
    } else if (expectedStrategyClass.equals(MimicDesugaringStrategy.class)) {
      testThrowableExtensionWithMimicDesugaringStrategy();
    } else if (expectedStrategyClass.equals(NullDesugaringStrategy.class)) {
      testThrowableExtensionWithNullDesugaringStrategy();
    } else {
      fail("unrecognized expected strategy class " + expectedStrategyClassName);
    }
  }

  private static int countOccurrences(String string, String substring) {
    int i = 0;
    int count = 0;
    while ((i = string.indexOf(substring, i)) >= 0) {
      ++count;
      i = i + string.length();
    }
    return count;
  }

  /** A mocked closeable class, which we can query the closedness. */
  private abstract static class AbstractResource {
    private final boolean exceptionOnClose;
    private boolean closed;

    protected AbstractResource(boolean exceptionOnClose) {
      this.exceptionOnClose = exceptionOnClose;
    }

    boolean isClosed() {
      return closed;
    }

    void internalClose() throws IOException {
      if (exceptionOnClose) {
        throw new IOException("intended exception");
      }
      closed = true;
    }
  }
}
