// 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.dex.code.DexInstruction;
import com.android.tools.r8.dex.code.DexInvokeVirtual;
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;

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;
    };
  }
}

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.inlinerOptions().enableInlining = false;
              options.enableStringConcatenationOptimization = 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(DexInstruction[] instructions) {
    for (DexInstruction instr : instructions) {
      if (instr instanceof DexInvokeVirtual) {
        DexInvokeVirtual invokeVirtual = (DexInvokeVirtual) instr;
        DexMethod invokedMethod = invokeVirtual.getMethod();
        if (invokedMethod.holder.getName().endsWith("StringBuilder")) {
          assertNotEquals("append", invokedMethod.name.toString());
        }
      }
    }
  }
}
