// 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.ir.optimize.outliner.b111893131;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.VmTestRunner;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.InvokeVirtual;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;

class TestClass {
  public interface Act {
    // Need both builder and arg to create code snippets for outline candidates.
    String get(StringBuilder builder, String arg);
  }

  public static void main(String[] args) {
    System.out.println(test(new TestClass("OK").toAct(), new StringBuilder(), "1"));
  }

  // Need to pass Act and call #get to create private instance lambda$
  private static String test(Act act, StringBuilder builder, String arg) {
    // Outline candidate
    builder.append(arg).append(arg).append(arg);
    act.get(builder, "#");
    return builder.toString();
  }

  private final String foo;

  TestClass(String foo) {
    this.foo = foo;
  }

  private Act toAct() {
    return (builder, arg) -> {
      // Outline candidate
      builder.append(arg).append(arg).append(arg);
      return foo;
    };
  }
}

@RunWith(VmTestRunner.class)
public class B111893131 extends TestBase {

  @Test
  public void test() throws Exception {
    String javaResult = runOnJava(TestClass.class);

    R8Command.Builder builder = R8Command.builder();
    builder.addProgramFiles(ToolHelper.getClassFileForTestClass(TestClass.class));
    builder.addProgramFiles(ToolHelper.getClassFileForTestClass(TestClass.Act.class));
    builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
    builder.setMinApiLevel(ToolHelper.getMinApiLevelForDexVm().getLevel());
    builder.setDisableMinification(true);
    String config = keepMainProguardConfiguration(TestClass.class);
    builder.addProguardConfiguration(ImmutableList.of(config), Origin.unknown());
    AndroidApp app = ToolHelper.runR8(builder.build(), options -> {
      // To trigger outliner, set # of expected outline candidate as threshold.
      options.outline.threshold = 2;
      options.enableInlining = false;
    });
    ProcessResult result = runOnArtRaw(app, TestClass.class);
    assertEquals(result.toString(), 0, result.exitCode);
    assertEquals(javaResult, result.stdout);

    CodeInspector inspector = new CodeInspector(app);
    ClassSubject classSubject = inspector.clazz(TestClass.class);
    assertThat(classSubject, isPresent());
    DexClass clazz = classSubject.getDexProgramClass();
    clazz.forEachMethod(encodedMethod -> {
      Code code = encodedMethod.getCode();
      assertTrue(code.isDexCode());
      DexCode dexCode = code.asDexCode();
      verifyAbsenceOfStringBuilderAppend(dexCode.instructions);
    });
  }

  private void verifyAbsenceOfStringBuilderAppend(Instruction[] instructions) {
    for (Instruction instr : instructions) {
      if (instr instanceof InvokeVirtual) {
        InvokeVirtual invokeVirtual = (InvokeVirtual) instr;
        DexMethod invokedMethod = invokeVirtual.getMethod();
        if (invokedMethod.holder.getName().endsWith("StringBuilder")) {
          assertNotEquals("append", invokedMethod.name.toString());
        }
      }
    }
  }

}
