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

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

import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.D8Command.Builder;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.smali.SmaliTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.util.Base64;
import java.util.Set;
import org.junit.Test;

public class Regress37740372 extends SmaliTestBase {

  /*
    Binary class file data for a java.lang.Object stub implementation. Runnong javap -c on the
    bytecode produces the following output:

    Compiled from "Object.java"
    public class java.lang.Object {
      public java.lang.Object();
        Code:
           0: new           #1                  // class java/lang/RuntimeException
           3: dup
           4: ldc           #2                  // String Stub!
           6: invokespecial #3                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
           9: athrow

      protected java.lang.Object clone() throws java.lang.CloneNotSupportedException;
        Code:
           0: new           #1                  // class java/lang/RuntimeException
           3: dup
           4: ldc           #2                  // String Stub!
           6: invokespecial #3                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
           9: athrow

      public boolean equals(java.lang.Object);
        Code:
           0: new           #1                  // class java/lang/RuntimeException
           3: dup
           4: ldc           #2                  // String Stub!
           6: invokespecial #3                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
           9: athrow

      protected void finalize() throws java.lang.Throwable;
        Code:
           0: new           #1                  // class java/lang/RuntimeException
           3: dup
           4: ldc           #2                  // String Stub!
           6: invokespecial #3                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
           9: athrow

      public final native java.lang.Class<?> getClass();

      public native int hashCode();

      public final native void notify();

      public final native void notifyAll();

      public java.lang.String toString();
        Code:
           0: new           #1                  // class java/lang/RuntimeException
           3: dup
           4: ldc           #2                  // String Stub!
           6: invokespecial #3                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
           9: athrow

      public final void wait() throws java.lang.InterruptedException;
        Code:
           0: new           #1                  // class java/lang/RuntimeException
           3: dup
           4: ldc           #2                  // String Stub!
           6: invokespecial #3                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
           9: athrow

      public final void wait(long) throws java.lang.InterruptedException;
        Code:
           0: new           #1                  // class java/lang/RuntimeException
           3: dup
           4: ldc           #2                  // String Stub!
           6: invokespecial #3                  // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
           9: athrow

      public final native void wait(long, int) throws java.lang.InterruptedException;
    }
  */
  String javaLangObjectClassFile =
      "yv66vgAAADEALwcAJwgAKAoAAQApBwAqAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1i" +
          "ZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABJMamF2YS9sYW5nL09iamVjdDsB" +
          "AAVjbG9uZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAKRXhjZXB0aW9ucwcAKwEABmVxdWFscwEA" +
          "FShMamF2YS9sYW5nL09iamVjdDspWgEAAW8BAAhmaW5hbGl6ZQcALAEACGdldENsYXNzAQATKClM" +
          "amF2YS9sYW5nL0NsYXNzOwEACVNpZ25hdHVyZQEAFigpTGphdmEvbGFuZy9DbGFzczwqPjsBAAho" +
          "YXNoQ29kZQEAAygpSQEABm5vdGlmeQEACW5vdGlmeUFsbAEACHRvU3RyaW5nAQAUKClMamF2YS9s" +
          "YW5nL1N0cmluZzsBAAR3YWl0BwAtAQAEKEopVgEABm1pbGxpcwEAAUoBAAUoSkkpVgEAClNvdXJj" +
          "ZUZpbGUBAAtPYmplY3QuamF2YQEAGmphdmEvbGFuZy9SdW50aW1lRXhjZXB0aW9uAQAFU3R1YiEM" +
          "AAUALgEAEGphdmEvbGFuZy9PYmplY3QBACRqYXZhL2xhbmcvQ2xvbmVOb3RTdXBwb3J0ZWRFeGNl" +
          "cHRpb24BABNqYXZhL2xhbmcvVGhyb3dhYmxlAQAeamF2YS9sYW5nL0ludGVycnVwdGVkRXhjZXB0" +
          "aW9uAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACEABAAAAAAAAAAMAAEABQAGAAEABwAAADQAAwAB" +
          "AAAACrsAAVkSArcAA78AAAACAAgAAAAGAAEAAAAEAAkAAAAMAAEAAAAKAAoACwAAAAQADAANAAIA" +
          "BwAAADQAAwABAAAACrsAAVkSArcAA78AAAACAAgAAAAGAAEAAAAFAAkAAAAMAAEAAAAKAAoACwAA" +
          "AA4AAAAEAAEADwABABAAEQABAAcAAAA+AAMAAgAAAAq7AAFZEgK3AAO/AAAAAgAIAAAABgABAAAA" +
          "BgAJAAAAFgACAAAACgAKAAsAAAAAAAoAEgALAAEABAATAAYAAgAHAAAANAADAAEAAAAKuwABWRIC" +
          "twADvwAAAAIACAAAAAYAAQAAAAcACQAAAAwAAQAAAAoACgALAAAADgAAAAQAAQAUAREAFQAWAAEA" +
          "FwAAAAIAGAEBABkAGgAAAREAGwAGAAABEQAcAAYAAAABAB0AHgABAAcAAAA0AAMAAQAAAAq7AAFZ" +
          "EgK3AAO/AAAAAgAIAAAABgABAAAADAAJAAAADAABAAAACgAKAAsAAAARAB8ABgACAAcAAAA0AAMA" +
          "AQAAAAq7AAFZEgK3AAO/AAAAAgAIAAAABgABAAAADQAJAAAADAABAAAACgAKAAsAAAAOAAAABAAB" +
          "ACAAEQAfACEAAgAHAAAAPgADAAMAAAAKuwABWRICtwADvwAAAAIACAAAAAYAAQAAAA4ACQAAABYA" +
          "AgAAAAoACgALAAAAAAAKACIAIwABAA4AAAAEAAEAIAERAB8AJAABAA4AAAAEAAEAIAABACUAAAAC" +
          "ACY=";

  private void assertIsJavaLangObjet(ClassSubject clazz) {
    assertTrue(clazz.getOriginalDescriptor().equals("Ljava/lang/Object;"));
    assertNull(clazz.getDexClass().superType);
  }

  private void checkApplicationOnlyHasJavaLangObject(AndroidApp app) throws Throwable {
    CodeInspector inspector = new CodeInspector(app);
    inspector.forAllClasses(this::assertIsJavaLangObjet);
  }

  static class MemoryConsumer extends DexIndexedConsumer.ForwardingConsumer {
    byte[] data;

    public MemoryConsumer() {
      super(null);
    }

    @Override
    public void accept(
        int fileIndex, ByteDataView data, Set<String> descriptors, DiagnosticsHandler handler) {
      assertEquals(0, fileIndex);
      this.data = data.copyByteData();
    }
  }

  @Test
  public void test() throws Throwable {
    // Build an application with the java.lang.Object stub from a class file.
    MemoryConsumer consumer = new MemoryConsumer();
    AndroidAppConsumers appConsumer = new AndroidAppConsumers();
    D8.run(
        D8Command.builder()
            .setProgramConsumer(appConsumer.wrapProgramConsumer(consumer))
            .addClassProgramData(
                Base64.getDecoder().decode(javaLangObjectClassFile), EmbeddedOrigin.INSTANCE)
            .build());
    checkApplicationOnlyHasJavaLangObject(appConsumer.build());

    // Build an application with the java.lang.Object stub from a dex file.
    Builder builder = D8Command.builder();
    builder.addDexProgramData(consumer.data, Origin.unknown());
    appConsumer = new AndroidAppConsumers(builder);
    D8.run(builder.build());
    checkApplicationOnlyHasJavaLangObject(appConsumer.build());
  }
}
