// Copyright (c) 2019, 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.proguard.rules;

import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.fail;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withNoneRuntime().build();
  }

  public NegatedClassMemberTest(TestParameters parameters) {

  }

  @Test
  public void testProguard() {
    try {
      testForProguard()
          .addProgramClasses(
              NegatedClassMemberTestClassA.class,
              NegatedClassMemberTestClassB.class,
              NegatedClassMemberTestClassC.class)
          .addKeepRules(getKeepRule())
          .compile();

      // For some reason, Proguard fails with "The output jar is empty". One likely explanation is
      // that Proguard only keeps classes that have a field y with type "!long", which is not a
      // valid type name, and therefore never matches anything.
      fail("Expected Proguard to fail with \"The output jar is empty\"");
    } catch (CompilationFailedException e) {
      assertThat(e.getMessage(), containsString("The output jar is empty"));
    }
  }

  @Test
  public void testR8() throws Exception {
    try {
      testForR8(Backend.DEX)
          .addProgramClasses(
              NegatedClassMemberTestClassA.class,
              NegatedClassMemberTestClassB.class,
              NegatedClassMemberTestClassC.class)
          .addKeepRules(getKeepRule())
          .compileWithExpectedDiagnostics(this::checkDiagnostics);
    } catch (CompilationFailedException e) {
      return;
    }
    fail("Expected R8 to fail during parsing of the Proguard configuration file");
  }

  private void checkDiagnostics(TestDiagnosticMessages diagnostics) {
    int expectedOffset = getKeepRule().indexOf("!");
    int expectedColumn = expectedOffset + 1;
    diagnostics
        .assertOnlyErrors()
        .assertErrorsMatch(
            diagnosticMessage(
                allOf(
                    containsString(":1:" + expectedColumn),
                    containsString(
                        "Unexpected character '!': "
                            + "The negation character can only be used to negate access flags"),
                    containsString(
                        StringUtils.join(
                            "\n",
                            "-keepclasseswithmembers class ** { long x; !long y; }",
                            "                                           ^")))));
  }

  private String getKeepRule() {
    return "-keepclasseswithmembers class ** { long x; !long y; }";
  }
}

class NegatedClassMemberTestClassA {

  long x = System.currentTimeMillis();
}

class NegatedClassMemberTestClassB {

  long x = System.currentTimeMillis();
  private long y = System.currentTimeMillis();
}

class NegatedClassMemberTestClassC {

  long x = System.currentTimeMillis();
  int y = (int) System.currentTimeMillis();
}
