// 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;

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

import com.android.tools.r8.DataResourceProvider.Visitor;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.dump.DumpOptions;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

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

  public AndroidAppDumpsTest(TestParameters parameters) {
    parameters.assertNoneRuntime();
  }

  @Test
  public void test() throws Exception {
    InternalOptions options = new InternalOptions();
    options.dumpOptions = DumpOptions.builder(Tool.D8).build();

    String dataResourceName = "my-resource.bin";
    byte[] dataResourceData = new byte[] {1, 2, 3};

    Path dexForB =
        testForD8().addProgramClasses(B.class).setMinApi(AndroidApiLevel.B).compile().writeToZip();

    AndroidApp appIn =
        AndroidApp.builder(options.reporter)
            .addClassProgramData(ToolHelper.getClassAsBytes(A.class), origin("A"))
            .addClassProgramData(ToolHelper.getClassAsBytes(A.class), origin("A"))
            .addClassProgramData(ToolHelper.getClassAsBytes(A.class), origin("A"))
            .addProgramFile(dexForB)
            .addClasspathResourceProvider(provider(B.class))
            .addClasspathResourceProvider(provider(B.class))
            .addClasspathResourceProvider(provider(B.class))
            .addLibraryResourceProvider(provider(C.class))
            .addLibraryResourceProvider(provider(C.class))
            .addLibraryResourceProvider(provider(C.class))
            .addProgramResourceProvider(
                createDataResourceProvider(
                    dataResourceName, dataResourceData, origin(dataResourceName)))
            .build();

    Path dumpFile = temp.newFolder().toPath().resolve("dump.zip");
    appIn.dump(dumpFile, options.dumpOptions, options.reporter, options.dexItemFactory());

    AndroidApp appOut = AndroidApp.builder(options.reporter).addDump(dumpFile).build();
    assertEquals(1, appOut.getClassProgramResourcesForTesting().size());
    assertEquals(
        DescriptorUtils.javaTypeToDescriptor(A.class.getTypeName()),
        appOut.getClassProgramResourcesForTesting().get(0).getClassDescriptors().iterator().next());

    assertEquals(1, appOut.getDexProgramResourcesForTesting().size());

    assertEquals(1, appOut.getClasspathResourceProviders().size());
    assertEquals(
        DescriptorUtils.javaTypeToDescriptor(B.class.getTypeName()),
        appOut.getClasspathResourceProviders().get(0).getClassDescriptors().iterator().next());

    assertEquals(1, appOut.getLibraryResourceProviders().size());
    assertEquals(
        DescriptorUtils.javaTypeToDescriptor(C.class.getTypeName()),
        appOut.getLibraryResourceProviders().get(0).getClassDescriptors().iterator().next());

    Box<Boolean> foundData = new Box<>(false);
    for (ProgramResourceProvider provider : appOut.getProgramResourceProviders()) {
      DataResourceProvider dataProvider = provider.getDataResourceProvider();
      if (dataProvider != null) {
        dataProvider.accept(
            new Visitor() {
              @Override
              public void visit(DataDirectoryResource directory) {}

              @Override
              public void visit(DataEntryResource file) {
                if (file.getName().equals(dataResourceName)) {
                  foundData.set(true);
                }
              }
            });
      }
    }
    assertTrue(foundData.get());
  }

  private ProgramResourceProvider createDataResourceProvider(
      String name, byte[] content, Origin origin) {
    return new ProgramResourceProvider() {
      @Override
      public Collection<ProgramResource> getProgramResources() throws ResourceException {
        return Collections.emptyList();
      }

      @Override
      public DataResourceProvider getDataResourceProvider() {
        return new DataResourceProvider() {
          @Override
          public void accept(Visitor visitor) throws ResourceException {
            visitor.visit(
                new DataEntryResource() {
                  @Override
                  public InputStream getByteStream() throws ResourceException {
                    return new ByteArrayInputStream(content);
                  }

                  @Override
                  public String getName() {
                    return name;
                  }

                  @Override
                  public Origin getOrigin() {
                    return origin;
                  }
                });
          }
        };
      }
    };
  }

  private Origin origin(String name) {
    return new Origin(Origin.root()) {
      @Override
      public String part() {
        return name;
      }
    };
  }

  private ClassFileResourceProvider provider(Class<?> clazz) {
    return new ClassFileResourceProvider() {
      @Override
      public Set<String> getClassDescriptors() {
        return Collections.singleton(DescriptorUtils.javaTypeToDescriptor(clazz.getTypeName()));
      }

      @Override
      public ProgramResource getProgramResource(String descriptor) {
        try {
          return ProgramResource.fromBytes(
              origin(clazz.getTypeName()),
              Kind.CF,
              ToolHelper.getClassAsBytes(clazz),
              getClassDescriptors());
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    };
  }

  public static class A {}

  public static class B {}

  public static class C {}
}
