// 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.tracereferences;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DiagnosticsChecker;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.io.IOException;
import java.nio.file.Path;
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 TraceReferencesMissingReferencesInDexTest extends TestBase {
  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withNoneRuntime().build();
  }

  public TraceReferencesMissingReferencesInDexTest(TestParameters parameters) {
    parameters.assertNoneRuntime();
  }

  static class MissingReferencesConsumer implements TraceReferencesConsumer {

    boolean acceptTypeCalled;
    boolean acceptFieldCalled;
    boolean acceptMethodCalled;

    @Override
    public void acceptType(TracedClass tracedClass, DiagnosticsHandler handler) {
      acceptTypeCalled = true;
      assertEquals(Reference.classFromClass(Target.class), tracedClass.getReference());
      assertTrue(tracedClass.isMissingDefinition());
    }

    @Override
    public void acceptField(TracedField tracedField, DiagnosticsHandler handler) {
      acceptFieldCalled = true;
      assertEquals(
          Reference.classFromClass(Target.class), tracedField.getReference().getHolderClass());
      assertEquals("field", tracedField.getReference().getFieldName());
      assertTrue(tracedField.isMissingDefinition());
    }

    @Override
    public void acceptMethod(TracedMethod tracedMethod, DiagnosticsHandler handler) {
      acceptMethodCalled = true;
      assertEquals(
          Reference.classFromClass(Target.class), tracedMethod.getReference().getHolderClass());
      assertEquals("target", tracedMethod.getReference().getMethodName());
      assertTrue(tracedMethod.isMissingDefinition());
    }
  }

  private void missingClassReferenced(Path sourceDex) throws Throwable {
    DiagnosticsChecker diagnosticsChecker = new DiagnosticsChecker();
    MissingReferencesConsumer consumer = new MissingReferencesConsumer();

    try {
      TraceReferences.run(
          TraceReferencesCommand.builder(diagnosticsChecker)
              .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
              .addSourceFiles(sourceDex)
              .setConsumer(consumer)
              .build());
      fail("Expected compilation to fail");
    } catch (CompilationFailedException e) {
      // Expected.
    }

    assertTrue(consumer.acceptTypeCalled);
    assertTrue(consumer.acceptFieldCalled);
    assertTrue(consumer.acceptMethodCalled);
  }

  @Test
  public void missingClassReferencedInDexArchive() throws Throwable {
    missingClassReferenced(
        testForD8(Backend.DEX).addProgramClasses(Source.class).compile().writeToZip());
  }

  @Test
  public void missingClassReferencedInDexFile() throws Throwable {
    missingClassReferenced(
        testForD8(Backend.DEX)
            .addProgramClasses(Source.class)
            .compile()
            .writeToDirectory()
            .resolve("classes.dex"));
  }

  private void missingFieldAndMethodReferenced(Path sourceDex) throws Throwable {
    DiagnosticsChecker diagnosticsChecker = new DiagnosticsChecker();
    MissingReferencesConsumer consumer = new MissingReferencesConsumer();

    try {
      TraceReferences.run(
          TraceReferencesCommand.builder(diagnosticsChecker)
              .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
              .addSourceFiles(sourceDex)
              .setConsumer(consumer)
              .build());
      fail("Expected compilation to fail");
    } catch (CompilationFailedException e) {
      // Expected.
    }

    assertFalse(consumer.acceptTypeCalled);
    assertTrue(consumer.acceptFieldCalled);
    assertTrue(consumer.acceptMethodCalled);
  }

  @Test
  public void missingFieldAndMethodReferencedInDexArchive() throws Throwable {
    missingFieldAndMethodReferenced(
        testForD8(Backend.DEX)
            .addProgramClasses(Source.class)
            .addProgramClassFileData(getClassWithTargetRemoved())
            .compile()
            .writeToZip());
  }

  @Test
  public void missingFieldAndMethodReferencedInDexFile() throws Throwable {
    missingFieldAndMethodReferenced(
        testForD8(Backend.DEX)
            .addProgramClasses(Source.class)
            .addProgramClassFileData(getClassWithTargetRemoved())
            .compile()
            .writeToDirectory()
            .resolve("classes.dex"));
  }

  private byte[] getClassWithTargetRemoved() throws IOException {
    return transformer(Target.class)
        .removeMethods((access, name, descriptor, signature, exceptions) -> name.equals("target"))
        .removeFields((access, name, descriptor, signature, value) -> name.equals("field"))
        .transform();
  }

  static class Target {
    public static int field;

    public static void target(int i) {}
  }

  static class Source {
    public static void source() {
      Target.target(Target.field);
    }
  }
}
