// 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 lambdadesugaring;

import java.io.Serializable;
import java.util.ArrayList;
import lambdadesugaring.legacy.Legacy;
import lambdadesugaring.other.OtherRefs;

public class LambdaDesugaring {
  interface I {
    String foo();
  }

  interface V {
    void foo();
  }

  interface VT<T> {
    void foo(T t);
  }

  interface P1<X> {
    X foo(int i);
  }

  interface I2 extends I {
  }

  interface I3 {
    String foo();
  }

  interface M1 {
  }

  interface M2 {
  }

  interface J {
    String foo(String a, int b, boolean c);
  }

  interface G {
    A foo();
  }

  interface H<T extends A> {
    T foo(T o);
  }

  interface K {
    Object foo(String a, String b, String c);
  }

  interface ObjectProvider {
    Object act();
  }

  interface S2Z {
    boolean foo(String a);
  }

  interface SS2Z {
    boolean foo(String a, String b);
  }

  interface ArrayTransformerA<T> {
    T[] transform(T[] a);
  }

  @SuppressWarnings("unchecked")
  interface ArrayTransformerB<T> {
    T[] transform(T... a);
  }

  static <T> void print(T[] a) {
    StringBuilder builder = new StringBuilder("{");
    String sep = "";
    for (T s : a) {
      builder.append(sep).append(s.toString());
      sep = ", ";
    }
    builder.append("}");
    System.out.println(builder.toString());
  }

  <T> T[] reorder(T[] a) {
    int size = a.length;
    for (int x = 0; x < size / 2; x++) {
      T t = a[x];
      a[x] = a[size - 1 - x];
      a[size - 1 - x] = t;
    }
    return a;
  }

  static void atA(ArrayTransformerA<Integer> f) {
    print(f.transform(new Integer[] { 1, 2, 3 }));
  }

  static void atB(ArrayTransformerB<String> f) {
    print(f.transform("A", "B", "C"));
  }

  public static String staticUnused() {
    return "ReleaseTests::staticUnused";
  }

  public static void testUnusedLambdas() {
    System.out.print("Before unused ... ");
    Object o = (I) LambdaDesugaring::staticUnused;
    System.out.println("after unused.");
  }

  class A {
    final String toString;

    A(String toString) {
      this.toString = toString;
    }

    @Override
    public String toString() {
      return toString;
    }
  }

  class B extends A {
    B(String toString) {
      super(toString);
    }
  }

  class C extends B {
    C(String toString) {
      super(toString);
    }
  }

  class D extends C {
    D(String toString) {
      super(toString);
    }
  }

  public static class Refs {
    public static String f(I i) {
      return i.foo();
    }

    public static void v(V v) {
      v.foo();
    }

    public static void vt(VT<String> v) {
      v.foo(null);
    }

    public static String p1(P1 p) {
      return p.foo(123).getClass().getCanonicalName();
    }

    public static String pSS2Z(SS2Z p) {
      return "" + p.foo("123", "321");
    }

    public static String pS2Z(S2Z p) {
      return "" + p.foo("123");
    }

    public static String p3(K k) {
      return k.foo("A", "B", "C").toString();
    }

    public static String g(ObjectProvider op) {
      return op.act().toString();
    }

    static class A extends OtherRefs {
      String fooInternal() {
        return "Refs::A::fooInternal()";
      }

      protected String fooProtected() {
        return "Refs::A::fooProtected()";
      }

      protected String fooProtectedOverridden() {
        return "Refs::A::fooProtectedOverridden()";
      }

      protected static String staticProtected() {
        return "Refs::A::staticProtected()";
      }

      static String staticInternal() {
        return "Refs::A::staticInternal()";
      }
    }

    public static class B extends A {
      public void test() {
        System.out.println(f(new A()::fooInternal));
        System.out.println(f(this::fooInternal));
        System.out.println(f(this::fooProtected));
        System.out.println(f(this::fooProtectedOverridden));
        System.out.println(f(this::fooPublic));
        System.out.println(f(this::fooInternal));

        System.out.println(f(super::fooProtectedOverridden));
        System.out.println(f(this::fooOtherProtected));
        System.out.println(f(this::fooOtherPublic));

        System.out.println(g(this::fooPrivate));
        System.out.println(g(new Integer(123)::toString));
        System.out.println(g(System::lineSeparator));

        System.out.println(f(A::staticInternal));
        System.out.println(f(A::staticProtected));
        System.out.println(f(B::staticPrivate));
        System.out.println(f(OtherRefs::staticOtherPublic));
        System.out.println(f(OtherRefs::staticOtherProtected));

        System.out.println(g(StringBuilder::new));
        System.out.println(g(OtherRefs.PublicInit::new));
        System.out.println(ProtectedInit.testProtected());
        System.out.println(g(ProtectedInit::new));
        System.out.println(g(InternalInit::new));
        System.out.println(PrivateInit.testPrivate());
        System.out.println(g(PrivateInit::new));

        System.out.println(p1(LambdaDesugaring[]::new));
        System.out.println(p1(Integer::new));
        System.out.println(p1(B::staticArray));

        System.out.println(pSS2Z(String::equalsIgnoreCase));
        System.out.println(pS2Z("123321"::contains));
        System.out.println(pS2Z(String::isEmpty));

        System.out.println(p3(B::fooConcat));

        v(D::new); // Discarding the return value
        vt((new ArrayList<String>())::add);

        I3 i3 = this::fooPrivate;
        System.out.println(f(i3::foo));
      }

      private static String staticPrivate() {
        return "Refs::B::staticPrivate()";
      }

      private String fooPrivate() {
        return "Refs::B::fooPrivate()";
      }

      String fooInternal() {
        return "Refs::B::fooInternal()";
      }

      public static StringBuilder fooConcat(Object... objs) {
        StringBuilder builder = new StringBuilder("Refs::B::fooConcat(");
        String sep = "";
        for (Object obj : objs) {
          builder.append(sep).append(obj.toString());
          sep = ", ";
        }
        return builder.append(")");
      }

      @Override
      protected String fooProtectedOverridden() {
        return "Refs::B::fooProtectedOverridden()";
      }

      public String fooPublic() {
        return "Refs::B::fooPublic()";
      }

      static int[] staticArray(int size) {
        return new int[size];
      }
    }

    static class D {
      D() {
        System.out.println("Refs::D::init()");
      }
    }

    public static class ProtectedInit extends OtherRefs.PublicInit {
      protected ProtectedInit() {
      }

      static String testProtected() {
        return g(ProtectedInit::new);
      }

      @Override
      public String toString() {
        return "OtherRefs::ProtectedInit::init()";
      }
    }

    static class InternalInit extends ProtectedInit {
      InternalInit() {
      }

      @Override
      public String toString() {
        return "Refs::InternalInit::init()";
      }
    }

    static class PrivateInit extends InternalInit {
      private PrivateInit() {
      }

      static String testPrivate() {
        return g(PrivateInit::new);
      }

      @Override
      public String toString() {
        return "Refs::PrivateInit::init()";
      }
    }
  }

  public void testLambdasSimple() {
    System.out.println(f(() -> "testLambdasSimple#1"));
    System.out.println(
        g((a, b, c) -> "{" + a + ":" + b + ":" + c + "}",
            "testLambdasSimple#2", 123, true));
  }

  public void testLambdasSimpleWithCaptures() {
    String s = "<stirng>";
    long l = 1234567890123456789L;
    char c = '#';

    System.out.println(
        g((x, y, z) -> "{" + s + ":" + l + ":" + c + ":" + x + ":" + y + ":" + z + "}",
            "param1", 2, false));

    I i1 = () -> "i1";
    I i2 = () -> i1.foo() + ":i2";
    I i3 = () -> i2.foo() + ":i3";
    System.out.println(f(() -> "{" + i3.foo() + ":anonymous}"));
  }

  public void testInstructionPatchingWithCatchHandlers() {
    try {
      int a = 1, b = 0;
      System.out.println(f(() -> "testInstructionPatchingWithCatchHandlers:1"));
      System.out.println(f(() -> ("does not matter " + (a / b))));
    } catch (IndexOutOfBoundsException | ArithmeticException e) {
      System.out.println("testInstructionPatchingWithCatchHandlers:Divide By Zero");
    } catch (RuntimeException re) {
      throw re;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    int changes = -1;
    try {
      if (f(() -> "").isEmpty()) {
        changes = 32;
        System.out.println(f(() -> "testInstructionPatchingWithCatchHandlers:lambda"));
        throw new RuntimeException();
      } else {
        changes = 42;
        throw new RuntimeException();
      }
    } catch (Throwable t) {
      System.out.println("testInstructionPatchingWithCatchHandlers:changes=" + changes);
    }
  }

  public void testInstanceLambdaMethods() {
    Integer i = 12345;
    System.out.println(h(() -> new A("{testInstanceLambdaMethods:" + i + "}")));
  }

  @SuppressWarnings("unchecked")
  private void testEnforcedSignatureHelper() {
    H h = ((H<B>) x -> new B("{testEnforcedSignature:" + x + "}"));
    System.out.println(h.foo(new A("A")).toString());
  }

  public void testEnforcedSignature() {
    String capture = "capture";
    System.out.println(i(x -> new B("{testEnforcedSignature:" + x + "}")));
    System.out.println(i(x -> new B("{testEnforcedSignature:" + capture + "}")));

    try {
      testEnforcedSignatureHelper();
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }

    atA(t -> new LambdaDesugaring().reorder(t));
    atB(t -> new LambdaDesugaring().reorder(t));
  }

  public void testMultipleInterfaces() {
    System.out.println(j((I2 & M1 & I3 & M2) () -> "{testMultipleInterfaces:1}"));

    Object o = (I2 & M1 & I3 & M2) () -> "{testMultipleInterfaces:2}";
    M1 m1 = (M1) o;
    M2 m2 = (M2) m1;
    I i = (I) m2;
    System.out.println(((I3) i).foo());

    o = (I2 & Serializable & M2) () -> "{testMultipleInterfaces:3}";
    m2 = (M2) o;
    Serializable s = (Serializable) m2;
    System.out.println(((I) s).foo());
  }

  public void testBridges() {
    k((Legacy.BH) (x -> x), "{testBridges:1}");
    k((Legacy.BK<Legacy.D> & Serializable) (x -> x), new Legacy.D("{testBridges:2}"));
    // k((Legacy.BL) (x -> x), new Legacy.B("{testBridges:3}")); crashes javac
    k((Legacy.BM) (x -> x), new Legacy.C("{testBridges:4}"));
  }

  public String f(I i) {
    return i.foo();
  }

  String g(J j, String a, int b, boolean c) {
    return j.foo(a, b, c);
  }

  String h(G g) {
    return g.foo().toString();
  }

  String i(H<B> h) {
    return h.foo(new B("i(H<B>)")).toString();
  }

  <T extends I2 & M1 & M2 & I3> String j(T l) {
    return ((I3) ((M2) ((M1) (((I2) l))))).foo();
  }

  static <T> void k(Legacy.BI<T> i, T v) {
    System.out.println(i.foo(v).toString());
  }

  static I statelessLambda() {
    return InstanceAndClassChecks::staticProvider;
  }

  static I statefulLambda() {
    return InstanceAndClassChecks.INSTANCE::instanceProvider;
  }

  static class InstanceAndClassChecks {
    static final InstanceAndClassChecks INSTANCE = new InstanceAndClassChecks();

    static void test() {
      assertSameInstance(
          InstanceAndClassChecks::staticProvider,
          InstanceAndClassChecks::staticProvider,
          "Instances must be same");
      assertSameInstance(
          InstanceAndClassChecks::staticProvider,
          statelessLambda(),
          "Instances must be same");

      assertDifferentInstance(
          INSTANCE::instanceProvider,
          INSTANCE::instanceProvider,
          "Instances must be different");
      assertDifferentInstance(
          INSTANCE::instanceProvider,
          statefulLambda(), "Instances must be different");
    }

    public static String staticProvider() {
      return "staticProvider";
    }

    public String instanceProvider() {
      return "instanceProvider";
    }

    static void assertSameInstance(I a, I b, String msg) {
      if (a != b) {
        throw new AssertionError(msg);
      }
    }

    static void assertDifferentInstance(I a, I b, String msg) {
      if (a == b) {
        throw new AssertionError(msg);
      }
    }
  }

  public static void main(String[] args) {
    LambdaDesugaring tests = new LambdaDesugaring();
    tests.testLambdasSimple();
    LambdaDesugaring.testUnusedLambdas();
    tests.testLambdasSimpleWithCaptures();
    tests.testInstructionPatchingWithCatchHandlers();
    tests.testInstanceLambdaMethods();
    tests.testEnforcedSignature();
    tests.testMultipleInterfaces();
    tests.testBridges();
    new Refs.B().test();
    if (isAndroid()) {
      InstanceAndClassChecks.test();
    }
  }

  static boolean isAndroid() {
    try {
      Class.forName("dalvik.system.VMRuntime");
      return true;
    } catch (Exception ignored) {
    }
    return false;
  }
}
