// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package trywithresources;

import java.io.Closeable;
import java.io.IOException;

public abstract class TryWithResources {
  // --- TEST SUPPORT ---

  interface Test {
    void test() throws Throwable;
  }

  private void test(Test test) {
    try {
      test.test();
    } catch (Throwable e) {
      dumpException(e);
    }
  }

  private void dumpException(Throwable e) {
    dumpException(e, "Exception: ");
  }

  private void dumpException(Throwable e, String indent) {
    assert e != null;
    System.out.println(indent + e.getMessage());

    indent = indent.replaceAll("[^:]", " ");

    Throwable cause = e.getCause();
    if (cause != null) {
      dumpException(cause, indent + "  cause: ");
    }

    Throwable[] suppressed = e.getSuppressed();
    for (int i = 0; i < suppressed.length; i++) {
      dumpException(suppressed[i], indent + "supp[" + i + "]: ");
    }
  }

  // --- TEST SYMBOLS ---

  static class Resource implements Closeable {
    final String tag;

    Resource(String tag) {
      this.tag = tag;
    }

    @Override
    public void close() throws IOException {
      Class<? extends Resource> cls = this.getClass();
      System.out.println("Closing " + tag + " (" +
          cls.getName().substring(TryWithResources.class.getName().length() + 1) + ")");
    }
  }

  // --- TEST ---

  class RegularTryWithResources {
    class RegularResource extends Resource {
      RegularResource(String tag) {
        super(tag);
      }
    }

    private void test() throws Throwable {
      test(2);
    }

    private void test(int level) throws Throwable {
      try (RegularResource a = new RegularResource("a" + level);
           RegularResource b = new RegularResource("b" + level)) {
        if (level > 0) {
          try {
            test(level - 1);
          } catch (Throwable e) {
            throw new RuntimeException("e" + level, e);
          }
        }
        throw new RuntimeException("primary cause");
      }
    }
  }

  // --- TEST ---

  class FailingTryWithResources {
    class FailingResource extends Resource {
      FailingResource(String tag) {
        super(tag);
      }

      @Override
      public void close() throws IOException {
        super.close();
        throw new RuntimeException("failed to close '" + tag + "'");
      }
    }

    private void test() throws Throwable {
      test(2);
    }

    private void test(int level) throws Throwable {
      try (FailingResource a = new FailingResource("a" + level);
           FailingResource b = new FailingResource("b" + level)) {
        if (level > 0) {
          try {
            test(level - 1);
          } catch (Throwable e) {
            throw new RuntimeException("e" + level, e);
          }
        }
        throw new RuntimeException("primary cause");
      }
    }
  }

  // --- TEST ---

  class ExplicitAddGetSuppressed {
    class RegularResource extends Resource {
      RegularResource(String tag) {
        super(tag);
      }

      @Override
      public void close() throws IOException {
        super.close();
        throw new RuntimeException("failed to close '" + tag + "'");
      }
    }

    private void test() throws Throwable {
      test(2);
    }

    private void test(int level) throws RuntimeException {
      try (RegularResource a = new RegularResource("a" + level);
           RegularResource b = new RegularResource("b" + level)) {
        if (level > 0) {
          try {
            test(level - 1);
          } catch (RuntimeException e) {
            // Just collect suppressed, but throw away the exception.
            RuntimeException re = new RuntimeException("e" + level);
            for (Throwable suppressed : e.getSuppressed()) {
              re.addSuppressed(suppressed);
            }
            throw re;
          }
        }
        throw new RuntimeException("primary cause");
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
  }

  // --- TEST ---

  interface Consumer {
    void act(RuntimeException re);
  }

  interface Supplier {
    Throwable[] get();
  }

  class AddGetSuppressedRoundTrip {
    private void test() throws Throwable {
      RuntimeException carrier = new RuntimeException("carrier");
      Consumer packer = carrier::addSuppressed;
      Supplier unpacker = carrier::getSuppressed;

      packer.act(new RuntimeException("original exception A"));
      packer.act(new RuntimeException("original exception Z"));

      for (Throwable unpacked : unpacker.get()) {
        dumpException(unpacked);
      }
    }
  }

  // --- TEST ---

  class UnreachableCatchAfterCallsRemoved {
    private void test() throws Throwable {
      RuntimeException main = new RuntimeException("main");
      RuntimeException origA = new RuntimeException("original exception A");
      RuntimeException origB = new RuntimeException("original exception Z");

      try {
        // After both calls below are removed, the whole catch
        // handler should be removed.
        main.addSuppressed(origA);
        main.addSuppressed(origB);
      } catch (Throwable t) {
        throw new RuntimeException("UNREACHABLE");
      }

      // Return value not used.
      main.getSuppressed();
    }
  }

  // --- MAIN TEST ---

  void test() throws Exception {
    System.out.println("----- TEST 1 -----");
    test(new RegularTryWithResources()::test);
    System.out.println("----- TEST 2 -----");
    test(new FailingTryWithResources()::test);
    System.out.println("----- TEST 3 -----");
    test(new ExplicitAddGetSuppressed()::test);
    System.out.println("----- TEST 4 -----");
    test(new AddGetSuppressedRoundTrip()::test);
    System.out.println("----- TEST 5 -----");
    test(new UnreachableCatchAfterCallsRemoved()::test);
    System.out.println("------------------");
  }
}
