// 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.shaking.attributes;

import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FieldSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  private final TestParameters parameters;
  private final String keepAttributes;

  @Parameterized.Parameters(name = "-keepattributes {1}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withNoneRuntime().build(),
        new String[] {".", "...", "XYZ,..", "XYZ,..,A.B"});
  }

  public KeepAttributesDotsTest(TestParameters parameters, String keepAttributes) {
    this.parameters = parameters;
    this.keepAttributes = keepAttributes;
  }

  @Test
  public void testProguard() throws ExecutionException, CompilationFailedException, IOException {
    testForProguard()
        .addInnerClasses(getClass())
        .addKeepAllClassesRule()
        .addKeepAttributes(keepAttributes)
        .addDontWarn(KeepAttributesDotsTest.class)
        .run(TestRuntime.getCheckedInJdk9(), Main.class)
        .assertSuccessWithOutputLines("Hello World!")
        .inspect(this::inspect);
  }

  @Test
  public void testR8() throws IOException, CompilationFailedException, ExecutionException {
    testForR8(Backend.CF)
        .addInnerClasses(getClass())
        .addKeepAttributes(keepAttributes)
        .addKeepAllClassesRule()
        .run(TestRuntime.getCheckedInJdk9(), Main.class)
        .assertSuccessWithOutputLines("Hello World!")
        .inspect(this::inspect);
  }

  private void inspect(CodeInspector inspector) {
    ClassSubject clazz = inspector.clazz(Main.class);
    assertTrue(clazz.getDexProgramClass().annotations().isEmpty());
    MethodSubject main = clazz.uniqueMethodWithName("main");
    assertTrue(main.getMethod().annotations().isEmpty());
    FieldSubject field = clazz.uniqueFieldWithName("field");
    assertTrue(field.getField().annotations().isEmpty());
    assertTrue(
        clazz.getDexProgramClass().sourceFile == null
            || clazz.getDexProgramClass().sourceFile.size == 0);
    assertNull(main.getLineNumberTable());
    assertTrue(main.getLocalVariableTable().isEmpty());
  }

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.METHOD})
  public @interface MethodRuntimeAnnotation {}

  @Retention(RetentionPolicy.CLASS)
  @Target({ElementType.METHOD})
  public @interface MethodCompileTimeAnnotation {}

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.TYPE})
  public @interface ClassRuntimeAnnotation {}

  @Retention(RetentionPolicy.CLASS)
  @Target({ElementType.TYPE})
  public @interface ClassCompileTimeAnnotation {}

  @ClassCompileTimeAnnotation
  @ClassRuntimeAnnotation
  public static class Main {

    public static class Inner<T> {}

    public Inner<Boolean> field;

    @MethodCompileTimeAnnotation
    @MethodRuntimeAnnotation
    public static void main(String[] args) {
      System.out.println("Hello World!");
    }
  }
}
