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

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import lambdadesugaringnplus.other.ClassWithDefaultPackagePrivate;
import lambdadesugaringnplus.other.InterfaceWithDefaultPackagePrivate;

public class LambdasWithStaticAndDefaultMethods {
  interface I {
    String iRegular();

    static String iStatic() {
      return "I::iStatic()";
    }

    default String iDefault() {
      return "I::iDefault()";
    }

    default String iDefaultOverridden() {
      return "I::iDefaultOverridden()";
    }

    default II stateless() {
      return () -> "I::stateless()";
    }

    default II stateful() {
      return () -> "I::captureThis(" + stateless().iRegular() + ")";
    }
  }

  static class C implements I {
    @Override
    public String iRegular() {
      return "C::iRegular()";
    }

    @Override
    public String iDefaultOverridden() {
      return "C::iDefaultOverridden()";
    }
  }

  interface II extends I {
    static String iStatic() {
      II ii = I::iStatic;
      return "II::iStatic(" + ((I) I::iStatic).iRegular() +
          "|" + ((II) ii::iDefaultOverridden).iRegular() +
          "|" + ((II) String::new).iRegular() +
          "|" + ((II) ii::iRegular).iRegular() + ")";
    }

    default String iDefaultOverridden() {
      return "II::iDefault(" + ((I) this::iDefault).iRegular() +
          "|" + ((II) "One-Two-Three"::intern).iRegular() +
          "|" + ((II) this::iDefault).iRegular() + ")";
    }
  }

  interface P {
    String get();
  }

  static void p(P p) {
    System.out.println(p.get());
  }

  interface X<T> {
    String foo(T t);
  }

  interface Y<T extends I> extends X<T> {
    String foo(T t);
  }

  interface Z extends Y<II> {
    String foo(II t);
  }

  interface G<T> {
    T foo(T t);
  }

  interface B38257361_I1<T extends Number> {
    default T copy(T t) {
      return t;
    }
  }

  interface B38257361_I2 extends B38257361_I1<Integer> {
    @Override
    default Integer copy(Integer t) {
      return B38257361_I1.super.copy(t);
    }
  }

  static class B38257361_C implements B38257361_I2 {
  }

  static class B38257361 {
    private B38257361_C c = new B38257361_C();

    public Integer test(Integer i) {
      return c.copy(i);
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    public Number test(Number n) {
      return ((B38257361_I1) c).copy(n);
    }

    public static void test() {
      B38257361 l = new B38257361();
      Integer i = new Integer(1);
      if (i.equals(l.test(i))) {
        System.out.println("Check 1: OK");
      } else {
        System.out.println("Check 1: NOT OK");
      }
      if (i.equals(l.test((Number) i))) {
        System.out.println("Check 2: OK");
      } else {
        System.out.println("Check 2: NOT OK");
      }
      try {
        Double d = new Double(1);
        if (d.equals(l.test((Number) d))) {
          System.out.println("Check 3: NOT OK, classCastException expected");
        } else {
          System.out.println("Check 3: NOT OK, classCastException expected");
        }
        System.out.println("Error, ClassCastException is expected");
      } catch (ClassCastException e) {
        // Class cast into the bridge method is expected
        System.out.println("OK, ClassCastException is expected");
      }
    }
  }

  static class B78901754 {
    public static class A {
      public final String msg;

      public A(String msg) {
        this.msg = msg;
      }
    }

    public static class B extends A {
      public B(String msg) {
        super(msg);
      }
    }

    public interface IAA {
      A[] foo(A[] p);
    }

    public interface IAB {
      A[] foo(B[] p);
    }

    public interface IBA {
      B[] foo(A[] p);
    }

    public interface IBB {
      B[] foo(B[] p);
    }

    public static A[] fooAA(A[] p) {
      return new A[]{new A("fooAA")};
    }

    public static A[] fooBA(B[] p) {
      return new A[]{new A("fooBA")};
    }

    public static B[] fooAB(A[] p) {
      return new B[]{new B("fooAB")};
    }

    public static B[] fooBB(B[] p) {
      return new B[]{new B("fooBB")};
    }

    public static void testAA(IAA i) {
      System.out.println(i.foo(null)[0].msg);
    }

    public static void testAB(IAB i) {
      System.out.println(i.foo(null)[0].msg);
    }

    public static void testBA(IBA i) {
      System.out.println(i.foo(null)[0].msg);
    }

    public static void testBB(IBB i) {
      System.out.println(i.foo(null)[0].msg);
    }

    public static void test() {
      testAA(B78901754::fooAA);
      testAA(B78901754::fooAB);
      // testAA(B78901754::fooBA); javac error: incompatible types: A[] cannot be converted to B[]
      // testAA(B78901754::fooBB); javac error: incompatible types: A[] cannot be converted to B[]

      testAB(B78901754::fooAA);
      testAB(B78901754::fooAB);
      testAB(B78901754::fooBA);
      testAB(B78901754::fooBB);

      // testBA(B78901754::fooAA); javac error: A[] cannot be converted to B[]
      testBA(B78901754::fooAB);
      // testBA(B78901754::fooBA); javac error: incompatible types: A[] cannot be converted to B[]
      // testBA(B78901754::fooBB); javac error: incompatible types: A[] cannot be converted to B[]

      // testBB(B78901754::fooAA); javac error: A[] cannot be converted to B[]
      testBB(B78901754::fooAB);
      // testBB(B78901754::fooBA); javac error: A[] cannot be converted to B[]
      testBB(B78901754::fooBB);
    }
  }

  interface B38257037_I1 {
    default Number getNumber() {
      return new Integer(1);
    }
  }

  interface B38257037_I2 extends B38257037_I1 {
    @Override
    default Double getNumber() {
      return new Double(2.3);
    }
  }

  static class B38257037_C implements B38257037_I2 {
  }

  /**
   * Check that bridges are generated.
   */
  static class B38257037 {
    private B38257037_C c = new B38257037_C();

    public Double test1() {
      return c.getNumber();
    }

    public Number test2() {
      return ((B38257037_I1) c).getNumber();
    }

    public static void test() {
      B38257037 l = new B38257037();
      if (l.test1() == 2.3) {
        System.out.println("Check 1: OK");
      } else {
        System.out.println("Check 1: NOT OK");
      }
      if (l.test2().equals(new Double(2.3))) {
        System.out.println("Check 2: OK");
      } else {
        System.out.println("Check 2: NOT OK");
      }
    }
  }

  interface B38306708_I {
    class $CC{
      static void print() {
        System.out.println("$CC");
      }
    }

    default String m() {
      return "ITop.m()";
    }
  }

  static class B38306708 {
    public static void test() {
      B38306708_I.$CC.print();
    }
  }

  interface B38308515_I {
    default String m() {
      return "m instance";
    }

    static String m(B38308515_I i) {
      return "m static";
    }
  }

  static class B38308515_C implements B38308515_I {
  }

  static class B38308515 {
    static void test() {
      B38308515_C c = new B38308515_C();
      System.out.println(c.m());
      System.out.println(B38308515_I.m(c));
    }
  }

  static class B38302860 {

    @SomeAnnotation(1)
    private interface AnnotatedInterface {

      @SomeAnnotation(2)
      void annotatedAbstractMethod();

      @SomeAnnotation(3)
      default void annotatedDefaultMethod() {
      }

      @SomeAnnotation(4)
      static void annotatedStaticMethod() {
        synchronized (AnnotatedInterface.class) { } // Do not inline
      }
    }

    @Retention(value = RetentionPolicy.RUNTIME)
    private @interface SomeAnnotation {
      int value();
    }

    private static boolean checkAnnotationValue(Annotation[] annotations, int value) {
      if (annotations.length != 1) {
        return false;
      }
      return annotations[0] instanceof SomeAnnotation
          && ((SomeAnnotation) annotations[0]).value() == value;
    }

    @SuppressWarnings("unchecked")
    static void test() throws Exception {
      if (checkAnnotationValue(AnnotatedInterface.class.getAnnotations(), 1)) {
        System.out.println("Check 1: OK");
      } else {
        System.out.println("Check 1: NOT OK");
      }

      if (checkAnnotationValue(
          AnnotatedInterface.class.getMethod("annotatedAbstractMethod").getAnnotations(), 2)) {
        System.out.println("Check 2: OK");
      } else {
        System.out.println("Check 2: NOT OK");
      }

      if (checkAnnotationValue(
          AnnotatedInterface.class.getMethod("annotatedDefaultMethod").getAnnotations(), 3)) {
        System.out.println("Check 3: OK");
      } else {
        System.out.println("Check 3: NOT OK");
      }

      // I don't know how to keep this method moved to the companion class
      // without the direct call.
      AnnotatedInterface.annotatedStaticMethod();
      if (checkAnnotationValue(
          getCompanionClassOrInterface().getMethod("annotatedStaticMethod").getAnnotations(), 4)) {
        System.out.println("Check 4: OK");
      } else {
        System.out.println("Check 4: NOT OK");
      }
    }

    private static Class getCompanionClassOrInterface() {
      try {
        return Class.forName("lambdadesugaringnplus."
            + "LambdasWithStaticAndDefaultMethods$B38302860$AnnotatedInterface$-CC");
      } catch (Exception e) {
        return AnnotatedInterface.class;
      }
    }
  }

  static class B62168701 {
    interface I extends Serializable {
      String getValue();
    }

    interface J {
      static void dump() {
        I i = () -> "B62168701 -- OK";
        System.out.println(i.getValue());
      }
    }

    static void test() {
      J.dump();
    }
  }

  static void z(Z p) {
    System.out.println(p.foo(null));
  }

  static void g(G<String[]> g) {
    StringBuilder builder = new StringBuilder("{");
    String sep = "";
    for (String s : g.foo(new String[] { "Arg0", "Arg1", "Arg2" })) {
      builder.append(sep).append(s);
      sep = ", ";
    }
    builder.append("}");
    System.out.println(builder.toString());
  }

  interface SuperChain {
    default String iMain() {
      return "SuperChain::iMain()";
    }
  }

  interface SuperChainDerived extends SuperChain {
    default String iMain() {
      return "SuperChainDerived::iMain(" + SuperChain.super.iMain() + ")";
    }
  }

  interface OtherSuperChain {
    default String iMain() {
      return "OtherSuperChain::iMain()";
    }
  }

  static class ClassWithSuperChain implements SuperChainDerived, OtherSuperChain {
    public String iMain() {
      return "ClassWithSuperChain::iMain(" + SuperChainDerived.super.iMain() + ")" + iMainImpl();
    }

    public String iMainImpl() {
      return "ClassWithSuperChain::iMain(" + SuperChainDerived.super.iMain() +
          " + " + OtherSuperChain.super.iMain() + ")";
    }
  }

  public static void main(String[] args) throws Exception {
    C c = new C();
    I i = c;

    c.iRegular();
    c.iDefault();
    c.iDefaultOverridden();
    I.iStatic();
    i.iRegular();
    i.iDefault();
    i.iDefaultOverridden();

    p(i.stateless()::iRegular);
    p(i.stateful()::iRegular);

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

    p(c::iRegular);
    p(c::iDefault);
    p(c::iDefaultOverridden);
    p(I::iStatic);
    p(i::iRegular);
    p(i::iDefault);
    p(i::iDefaultOverridden);

    II ii = i::iRegular;
    p(II::iStatic);
    p(ii::iRegular);
    p(ii::iDefault);
    p(ii::iDefaultOverridden);

    z(s -> "From Interface With Bridges");

    System.out.println(new ClassWithSuperChain().iMain());

    ClassWithDefaultPackagePrivate c2 = new ClassWithDefaultPackagePrivate();
    InterfaceWithDefaultPackagePrivate i2 = c2;

    c2.defaultFoo();
    i2.defaultFoo();
    InterfaceWithDefaultPackagePrivate.staticFoo();

    p(c2::defaultFoo);
    p(i2::defaultFoo);
    p(InterfaceWithDefaultPackagePrivate::staticFoo);
    p(c2.lambda()::foo);

    B38257361.test();
    B38257037.test();
    B38306708.test();
    B38308515.test();
    B38302860.test();
    B62168701.test();
    B78901754.test();
  }
}
