// Copyright (c) 2020, 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 com.android.tools.r8.desugar;

import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.StringResource;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.StringUtils;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class InvokeSuperToRewrittenDefaultMethodTest extends DesugaredLibraryTestBase {

  private static final String EXPECTED = StringUtils.lines("Y", "89");

  @Parameterized.Parameters(name = "{0}, old-rt:{1}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values());
  }

  private final TestParameters parameters;
  private final boolean rtWithoutConsumer;

  public InvokeSuperToRewrittenDefaultMethodTest(
      TestParameters parameters, boolean rtWithoutConsumer) {
    this.parameters = parameters;
    this.rtWithoutConsumer = rtWithoutConsumer;
  }

  private boolean needsDefaultInterfaceMethodDesugaring() {
    return parameters.isDexRuntime()
        && parameters.getApiLevel().isLessThan(apiLevelWithDefaultInterfaceMethodsSupport());
  }

  @Test
  public void testReference() throws Exception {
    assumeFalse(needsDefaultInterfaceMethodDesugaring());
    testForRuntime(parameters)
        .addInnerClasses(InvokeSuperToRewrittenDefaultMethodTest.class)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
  }

  @Test
  public void testDesugaring() throws Exception {
    assumeTrue(needsDefaultInterfaceMethodDesugaring());
    try {
      testForD8()
          .addInnerClasses(InvokeSuperToRewrittenDefaultMethodTest.class)
          .setMinApi(parameters.getApiLevel())
          .apply(
              b -> {
                if (rtWithoutConsumer) {
                  b.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.B));
                  // TODO(b/158543446): Remove this once enableCoreLibraryDesugaring is fixed.
                  b.getBuilder()
                      .addDesugaredLibraryConfiguration(
                          StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
                } else {
                  // TODO(b/158543446): Move this out to the shared builder once
                  //  enableCoreLibraryDesugaring is fixed.
                  b.enableCoreLibraryDesugaring(parameters.getApiLevel());
                }
              })
          .compileWithExpectedDiagnostics(
              diagnostics -> {
                if (rtWithoutConsumer) {
                  diagnostics.assertOnlyErrors();
                  // TODO(b/158543011): Should fail with a nice user error for invalid library.
                  diagnostics.assertErrorsMatch(
                      allOf(
                          diagnosticType(ExceptionDiagnostic.class),
                          diagnosticMessage(containsString("AssertionError"))));
                } else {
                  diagnostics.assertNoMessages();
                }
              })
          .addDesugaredCoreLibraryRunClassPath(
              this::buildDesugaredLibrary, parameters.getApiLevel())
          .run(parameters.getRuntime(), TestClass.class)
          .assertSuccessWithOutput(EXPECTED);
      assertFalse(rtWithoutConsumer);
    } catch (CompilationFailedException e) {
      assertTrue(rtWithoutConsumer);
    }
  }

  public interface CharConsumer extends Consumer<Character>, IntConsumer {

    void accept(char c);

    @Override
    default void accept(int value) {
      accept((char) value);
    }

    @Override
    default void accept(Character character) {
      accept(character.charValue());
    }

    @Override
    default Consumer<Character> andThen(Consumer<? super Character> after) {
      // Simple forward to the default method of the parent.
      // Must be rewritten to target the companion class of the rewritten Consumer type.
      return Consumer.super.andThen(after);
    }
  }

  public static class TestClass {

    public static void main(String[] args) {
      CharConsumer consumer = System.out::println;
      consumer.andThen((Consumer<? super Character>) c -> System.out.println((int) c)).accept('Y');
    }
  }
}
