// Copyright (c) 2016, 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.utils;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;

import com.android.tools.r8.utils.FeatureClassMapping.FeatureMappingException;
import com.google.common.collect.ImmutableList;
import java.util.List;
import org.junit.Test;

public class FeatureClassMappingTest {

  @Test
  public void testSimpleParse() throws Exception {

    List<String> lines =
        ImmutableList.of(
            "# Comment, don't care about contents: even more ::::",
            "com.google.base:base",
            "", // Empty lines allowed
            "com.google.feature1:feature1",
            "com.google.feature1:feature1", // Multiple definitions of the same predicate allowed.
            "com.google$:feature1",
            "_com.google:feature21",
            "com.google.*:feature32");
    FeatureClassMapping mapping = new FeatureClassMapping(lines);
  }

  private void ensureThrowsMappingException(List<String> lines) {
    try {
      new FeatureClassMapping(lines);
      assertFalse(true);
    } catch (FeatureMappingException e) {
      // Expected
    }
  }

  private void ensureThrowsMappingException(String string) {
    ensureThrowsMappingException(ImmutableList.of(string));
  }

  @Test
  public void testLookup() throws Exception {
    List<String> lines =
        ImmutableList.of(
            "com.google.Base:base",
            "",
            "com.google.Feature1:feature1",
            "com.google.Feature1:feature1", // Multiple definitions of the same predicate allowed.
            "com.google.different.*:feature1",
            "_com.Google:feature21",
            "com.google.bas42.*:feature42");
    FeatureClassMapping mapping = new FeatureClassMapping(lines);
    assertEquals(mapping.featureForClass("com.google.Feature1"), "feature1");
    assertEquals(mapping.featureForClass("com.google.different.Feature1"), "feature1");
    assertEquals(mapping.featureForClass("com.google.different.Foobar"), "feature1");
    assertEquals(mapping.featureForClass("com.google.Base"), "base");
    assertEquals(mapping.featureForClass("com.google.bas42.foo.bar.bar.Foo"), "feature42");
    assertEquals(mapping.featureForClass("com.google.bas42.f$o$o$.bar43.bar.Foo"), "feature42");
    assertEquals(mapping.featureForClass("_com.Google"), "feature21");
  }

  @Test
  public void testCatchAllWildcards() throws Exception {
    testBaseWildcard(true);
    testBaseWildcard(false);
    testNonBaseCatchAll();
  }

  private void testNonBaseCatchAll() throws FeatureMappingException {
    List<String> lines =
        ImmutableList.of(
            "com.google.Feature1:feature1",
            "*:nonbase",
            "com.strange.*:feature2");
    FeatureClassMapping mapping = new FeatureClassMapping(lines);
    assertEquals(mapping.featureForClass("com.google.Feature1"), "feature1");
    assertEquals(mapping.featureForClass("com.google.different.Feature1"), "nonbase");
    assertEquals(mapping.featureForClass("com.strange.different.Feature1"), "feature2");
    assertEquals(mapping.featureForClass("Feature1"), "nonbase");
    assertEquals(mapping.featureForClass("a.b.z.A"), "nonbase");
  }

  private void testBaseWildcard(boolean explicitBase) throws FeatureMappingException {
    List<String> lines =
        ImmutableList.of(
            "com.google.Feature1:feature1",
            explicitBase ? "*:base" : "",
            "com.strange.*:feature2");
    FeatureClassMapping mapping = new FeatureClassMapping(lines);
    assertEquals(mapping.featureForClass("com.google.Feature1"), "feature1");
    assertEquals(mapping.featureForClass("com.google.different.Feature1"), "base");
    assertEquals(mapping.featureForClass("com.strange.different.Feature1"), "feature2");
    assertEquals(mapping.featureForClass("Feature1"), "base");
    assertEquals(mapping.featureForClass("a.b.z.A"), "base");
  }

  @Test
  public void testWrongLines() throws Exception {
    // No colon.
    ensureThrowsMappingException("foo");
    ensureThrowsMappingException("com.google.base");
    // Two colons.
    ensureThrowsMappingException(ImmutableList.of("a:b:c"));

    // Empty identifier.
    ensureThrowsMappingException("com..google:feature1");

    // Ambiguous redefinition
    ensureThrowsMappingException(
        ImmutableList.of("com.google.foo:feature1", "com.google.foo:feature2"));
    ensureThrowsMappingException(
        ImmutableList.of("com.google.foo.*:feature1", "com.google.foo.*:feature2"));
  }
}
