// Copyright (c) 2018, 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.naming.b114554345;

import static junit.framework.TestCase.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.AndroidApp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class B114554345 extends TestBase {

  private final Backend backend;

  @Parameters(name = "backend: {0}")
  public static Backend[] data() {
    return ToolHelper.getBackends();
  }

  public B114554345(Backend backend) {
    this.backend = backend;
  }

  @Test
  public void test() throws Exception {
    AndroidApp input =
        AndroidApp.builder()
            .addProgramFiles(
                ToolHelper.getClassFilesForTestDirectory(
                    ToolHelper.getPackageDirectoryForTestPackage(this.getClass().getPackage()),
                    path -> !path.toString().contains("B114554345")))
            .build();
    AndroidApp output =
        compileWithR8(
            input,
            keepMainProguardConfiguration(TestDriver.class),
            options -> options.inlinerOptions().enableInlining = false,
            backend);
    String mainClass = TestDriver.class.getName();
    assertEquals(runOnJava(TestDriver.class), runOnVM(output, mainClass, backend));
  }
}

// Interface and two implementations.

interface Interface {
  Interface method();
}

class InterfaceImpl implements Interface {

  @Override
  public InterfaceImpl method() {
    System.out.println("In InterfaceImpl.method()");
    return this;
  }
}

class OtherInterfaceImpl extends InterfaceImpl {

  @Override
  public OtherInterfaceImpl method() {
    System.out.println("In OtherInterfaceImpl.method()");
    return this;
  }
}

// Sub-interface and three implementations.

interface SubInterface extends Interface {
  SubInterface method();
}

class SubInterfaceImpl implements SubInterface {

  @Override
  public SubInterfaceImpl method() {
    System.out.println("In SubInterfaceImpl.method()");
    return this;
  }
}

class OtherSubInterfaceImpl implements SubInterface {

  @Override
  public OtherSubInterfaceImpl method() {
    System.out.println("In OtherSubInterfaceImpl.method()");
    return this;
  }
}

class YetAnotherSubInterfaceImpl extends InterfaceImpl implements SubInterface {

  @Override
  public YetAnotherSubInterfaceImpl method() {
    System.out.println("In YetAnotherSubInterfaceImpl.method()");
    return this;
  }
}

class TestDriver {

  public static void main(String[] args) {
    foo(new InterfaceImpl());
    foo(new OtherInterfaceImpl());
    foo(new SubInterfaceImpl());
    foo(new YetAnotherSubInterfaceImpl());
    bar(new SubInterfaceImpl());
    bar(new OtherSubInterfaceImpl());
    bar(new YetAnotherSubInterfaceImpl());
  }

  private static void foo(Interface obj) {
    obj.method();
  }

  private static void bar(SubInterface obj) {
    obj.method();
  }
}
