// 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 com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
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;
    }
  }
}
