// Copyright (c) 2017, 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;

import com.android.tools.r8.ClassFileResourceProvider;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidApp.Builder;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.ThrowingBiFunction;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class FilteredClassPathTest {

  private void testPath(List<String> filters, List<String> positives, List<String> negatives) {
    FilteredClassPath path = makeFilteredClassPath(filters);
    Assert.assertTrue(
        positives.stream().map(FilteredClassPathTest::adaptFileSeparator).map(Paths::get)
            .allMatch(path::matchesFile));
    Assert.assertFalse(
        negatives.stream().map(FilteredClassPathTest::adaptFileSeparator).map(Paths::get)
            .allMatch(path::matchesFile));
  }

  private static String adaptFileSeparator(String s) {
    return s.replace('/', File.separatorChar);
  }

  private static FilteredClassPath makeFilteredClassPath(List<String> filters) {
    return makeFilteredClassPath(Paths.get("foo"), filters);
  }

  private static FilteredClassPath makeFilteredClassPath(Path path, List<String> filters) {
    return new FilteredClassPath(path,
        filters.stream().map(FilteredClassPathTest::adaptFileSeparator)
            .collect(ImmutableList.toImmutableList()));
  }

  @Test
  public void testFilterMatching() {
    testPath(ImmutableList.of("!boo"),
        ImmutableList.of("bool", "bo"),
        ImmutableList.of("boo"));
    testPath(ImmutableList.of("!*.boo"),
        ImmutableList.of("zoo.bar", "Fish.bool", "Cat.bo", "boo", "path/zoo.boo",
            "zoo.bool", "zoo.bo"),
        ImmutableList.of("mi.boo", ".boo"));
    testPath(ImmutableList.of("!*s/*.boo"),
        ImmutableList.of("zoo.bar", "Fish.bool", "Cat.bo", "boo", "path/zoo.boo", "sx/a.boo",
            "ass/boo", "s/x/.boo", "s/s/s.boo", "s/zoo.bool"),
        ImmutableList.of("mi.boo", ".boo", "ass/a.boo", "s/.boo", "asis/sos.boo"));
    testPath(ImmutableList.of("!**s/*.boo"),
        ImmutableList.of("zoo.bar", "Fish.bool", "Cat.bo", "boo", "path/zoo.boo", "sx/a.boo",
            "ass/boo", "s/x/.boo", "s/zoo.bool"),
        ImmutableList.of("mi.boo", ".boo", "ass/a.boo", "s/.boo", "asis/sos.boo", "s/s/s.boo",
            "xyz/abz/ass/.boo"));
    testPath(ImmutableList.of("!*.boo", "*.bar", "*.baz"),
        ImmutableList.of("sinz.bar", "song.baz", ".baz", ".bar"),
        ImmutableList.of("sinz.boo", ".boo", ".bang", "goo.bang", "s/foo.baz"));
  }

  private void testApplicationFiltered(
      ThrowingBiFunction<Builder, Collection<FilteredClassPath>, Builder, IOException> setter,
      Function<AndroidApp, List<String>> getter)
      throws IOException {
    Path androidJar = ToolHelper.getDefaultAndroidJar();
    AndroidApp app = setter.apply(
        AndroidApp.builder(),
        Collections.singletonList(makeFilteredClassPath(
            androidJar, ImmutableList.of("!java/lang/**.class", "java/util/**.class"))))
        .build();
    List<String> descriptors = getter.apply(app);
    Assert.assertTrue(descriptors.stream().noneMatch(s -> s.startsWith("Ljava/lang")));
    Assert.assertTrue(descriptors.stream().anyMatch(s -> s.startsWith("Ljava/util")));
    Assert.assertTrue(descriptors.stream().noneMatch(s -> s.startsWith("Lcom/android")));
  }

  @Test
  public void testLibraryFiltered() throws IOException {
    testApplicationFiltered(
        Builder::addFilteredLibraryArchives,
        app -> {
          ClassFileResourceProvider provider =
              Iterables.getOnlyElement(app.getLibraryResourceProviders());
          List<ProgramResource> resources =
              ListUtils.map(provider.getClassDescriptors(), provider::getProgramResource);
          return resources
              .stream()
              .flatMap(r -> r.getClassDescriptors().stream())
              .collect(Collectors.toList());
        });
  }

  private static Stream<ProgramResource> getClassProgramResources(ProgramResourceProvider reader) {
    try {
      return reader.getProgramResources().stream();
    } catch (ResourceException e) {
      return Stream.empty();
    }
  }

  @Test
  public void testProgramFiltered() throws IOException {
    testApplicationFiltered(
        Builder::addFilteredProgramArchives,
        app ->
            app.getProgramResourceProviders()
                .stream()
                .flatMap(FilteredClassPathTest::getClassProgramResources)
                .flatMap(r -> r.getClassDescriptors().stream())
                .collect(Collectors.toList()));
  }
}
