// Copyright (c) 2018, 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 static com.android.tools.r8.utils.DexInspectorMatchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DataResourceProvider;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DiagnosticsChecker;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.origin.ArchiveEntryOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.DexInspector;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharSource;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import org.junit.Test;

class A {
  private static String buildClassName(String className) {
    return A.class.getPackage().getName() + "." + className;
  }

  public static void main(String[] args) {
    try {
      Class bClass = Class.forName(buildClassName("B"));
      System.out.println("YES");
    } catch (ClassNotFoundException e) {
      System.out.println("NO");
    }
  }
}

class B {

}

public class LibraryProvidedProguardRulesTest extends TestBase {
  private void addTextJarEntry(JarOutputStream out, String name, String content) throws Exception {
    out.putNextEntry(new ZipEntry(name));
    ByteStreams.copy(
        CharSource.wrap(content).asByteSource(StandardCharsets.UTF_8).openBufferedStream(), out);
    out.closeEntry();
  }

  private AndroidApp runTest(List<String> rules, DiagnosticsHandler handler) throws Exception {
    Path jar = temp.newFile("test.jar").toPath();
    try (JarOutputStream out = new JarOutputStream(new FileOutputStream(jar.toFile()))) {
      addTestClassesToJar(out, A.class, B.class);
      for (int i =  0; i < rules.size(); i++) {
        String name = "META-INF/proguard/jar" + (i == 0 ? "" : i) + ".rules";
        addTextJarEntry(out, name, rules.get(i));
      }
    }

    try {
      R8Command command = (handler != null ? R8Command.builder(handler) : R8Command.builder())
          .addProgramFiles(jar)
          .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
          .build();
      return ToolHelper.runR8(command);
    } catch (CompilationFailedException e) {
      assertNotNull(handler);
      return null;
    }
  }

  private AndroidApp runTest(String rules, DiagnosticsHandler handler) throws Exception {
    return runTest(ImmutableList.of(rules), handler);
  }


  @Test
  public void keepOnlyA() throws Exception {
    AndroidApp app = runTest("-keep class " + A.class.getTypeName() +" {}", null);
    DexInspector inspector = new DexInspector(app);
    assertThat(inspector.clazz(A.class), isPresent());
    assertThat(inspector.clazz(B.class), not(isPresent()));
  }

  @Test
  public void keepOnlyB() throws Exception {
    AndroidApp app = runTest("-keep class **B {}", null);
    DexInspector inspector = new DexInspector(app);
    assertThat(inspector.clazz(A.class), not(isPresent()));
    assertThat(inspector.clazz(B.class), isPresent());
  }

  @Test
  public void keepBoth() throws Exception {
    AndroidApp app = runTest("-keep class ** {}", null);
    DexInspector inspector = new DexInspector(app);
    assertThat(inspector.clazz(A.class), isPresent());
    assertThat(inspector.clazz(B.class), isPresent());
  }

  @Test
  public void multipleFiles() throws Exception {
    AndroidApp app = runTest(ImmutableList.of("-keep class **A {}", "-keep class **B {}"), null);
    DexInspector inspector = new DexInspector(app);
    assertThat(inspector.clazz(A.class), isPresent());
    assertThat(inspector.clazz(B.class), isPresent());
  }

  private void checkOrigin(Origin origin) {
    assertTrue(origin instanceof ArchiveEntryOrigin);
    assertEquals(origin.part(), "META-INF/proguard/jar.rules");
    assertTrue(origin.parent() instanceof PathOrigin);
  }

  @Test
  public void syntaxError() throws Exception {
    DiagnosticsChecker checker = new DiagnosticsChecker();
    AndroidApp app = runTest("error", checker);
    assertNull(app);
    DiagnosticsChecker.checkDiagnostic(
        checker.errors.get(0), this::checkOrigin, 1, 1, "Expected char '-'");
  }

  @Test
  public void includeError() throws Exception {
    DiagnosticsChecker checker = new DiagnosticsChecker();
    AndroidApp app = runTest("-include other.rules", checker);
    assertNull(app);
    DiagnosticsChecker.checkDiagnostic(checker.errors.get(0), this::checkOrigin, 1, 10,
        "Options with file names are not supported");
  }

  class TestProvider implements ProgramResourceProvider, DataResourceProvider {

    @Override
    public Collection<ProgramResource> getProgramResources() throws ResourceException {
      byte[] bytes;
      try {
        bytes = ByteStreams.toByteArray(A.class.getResourceAsStream("A.class"));
      } catch (IOException e) {
        throw new ResourceException(Origin.unknown(), "Unexpected");
      }
      return ImmutableList.of(
          ProgramResource.fromBytes(Origin.unknown(), Kind.CF, bytes,
              Collections.singleton(DescriptorUtils.javaTypeToDescriptor(A.class.getTypeName()))));
    }

    @Override
    public DataResourceProvider getDataResourceProvider() {
      return this;
    }

    @Override
    public void accept(Visitor visitor) throws ResourceException {
      throw new ResourceException(Origin.unknown(), "Cannot provide data resources after all");
    }
  }

  @Test
  public void throwingDataResourceProvider() throws Exception {
    DiagnosticsChecker checker = new DiagnosticsChecker();
    try {
      R8Command command = R8Command.builder(checker)
          .addProgramResourceProvider(new TestProvider())
          .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
          .build();
      fail("Should not succeed");
    } catch (CompilationFailedException e) {
      DiagnosticsChecker.checkDiagnostic(
          checker.errors.get(0),
          origin -> assertSame(origin, Origin.unknown()),
          "Cannot provide data resources after all");
    }
  }
}
