// Copyright 2016 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.android.resources;

import static com.google.common.truth.Truth.assertThat;

import com.android.SdkConstants;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link RClassGenerator}.
 */
@RunWith(JUnit4.class)
public class RClassGeneratorTest {

  private Path temp;
  @Rule
  public final ExpectedException thrown = ExpectedException.none();

  @Before
  public void setUp() throws Exception {
    temp = Files.createTempDirectory(toString());
  }

  @Test
  public void plainInts() throws Exception {
    checkSimpleInts(true);
  }

  @Test
  public void nonFinalFields() throws Exception {
    checkSimpleInts(false);
  }

  private void checkSimpleInts(boolean finalFields) throws Exception {
    // R.txt with the real IDs after linking together libraries.
    ResourceSymbols symbolValues =
        createSymbolFile(
            "R.txt",
            "int attr agility 0x7f010000",
            "int attr dexterity 0x7f010001",
            "int drawable heart 0x7f020000",
            "int id someTextView 0x7f080000",
            "int integer maxNotifications 0x7f090000",
            "int string alphabet 0x7f100000",
            "int string ok 0x7f100001");
    // R.txt for the library, where the values are not the final ones (so ignore them). We only use
    // this to keep the # of inner classes small (exactly the set needed by the library).
    ResourceSymbols symbolsInLibrary =
        createSymbolFile(
            "lib.R.txt", "int attr agility 0x1", "int id someTextView 0x1", "int string ok 0x1");
    Path out = temp.resolve("classes");
    Files.createDirectories(out);
    RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), finalFields);
    writer.write("com.bar", symbolsInLibrary.asInitializers());

    Path packageDir = out.resolve("com/bar");
    checkFilesInPackage(packageDir, "R.class", "R$attr.class", "R$id.class", "R$string.class");
    Class<?> outerClass = checkTopLevelClass(out,
        "com.bar.R",
        "com.bar.R$attr",
        "com.bar.R$id",
        "com.bar.R$string");
    checkInnerClass(out,
        "com.bar.R$attr",
        outerClass,
        ImmutableMap.of("agility", 0x7f010000),
        ImmutableMap.<String, List<Integer>>of(),
        finalFields
    );
    checkInnerClass(out,
        "com.bar.R$id",
        outerClass,
        ImmutableMap.of("someTextView", 0x7f080000),
        ImmutableMap.<String, List<Integer>>of(),
        finalFields
    );
    checkInnerClass(out,
        "com.bar.R$string",
        outerClass,
        ImmutableMap.of("ok", 0x7f100001),
        ImmutableMap.<String, List<Integer>>of(),
        finalFields
    );
  }

  @Test
  public void checkFileWriteThrowsOnExisting() throws Exception {
    checkFileWriteThrowsOnExisting(SdkConstants.FN_COMPILED_RESOURCE_CLASS);
  }

  @Test
  public void checkInnerFileWriteThrowsOnExisting() throws Exception {
    checkFileWriteThrowsOnExisting("R$string.class");
  }

  private void checkFileWriteThrowsOnExisting(String existingFile) throws Exception {
    ResourceSymbols symbolValues =
        createSymbolFile("R.txt", "int string ok 0x7f100001");
    ResourceSymbols symbolsInLibrary =
        createSymbolFile("lib.R.txt", "int string ok 0x1");

    Path out = temp.resolve("classes");
    String packageName = "com";
    Path packageFolder = out.resolve(packageName);
    Files.createDirectories(packageFolder);

    RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), false);
    Files.write(packageFolder.resolve(existingFile), new byte[0]);

    try {
      writer.write(packageName, symbolsInLibrary.asInitializers());
    } catch (FileAlreadyExistsException e) {
      return;
    }
    throw new Exception("Expected to throw a FileAlreadyExistsException");
  }

  @Test
  public void emptyIntArrays() throws Exception {
    boolean finalFields = true;
    // Make sure we parse an empty array the way the R.txt writes it.
    ResourceSymbols symbolValues = createSymbolFile("R.txt", "int[] styleable ActionMenuView { }");
    ResourceSymbols symbolsInLibrary = symbolValues;
    Path out = temp.resolve("classes");
    Files.createDirectories(out);
    RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), finalFields);
    writer.write("com.testEmptyIntArray", symbolsInLibrary.asInitializers());

    Path packageDir = out.resolve("com/testEmptyIntArray");
    checkFilesInPackage(packageDir, "R.class", "R$styleable.class");
    Class<?> outerClass = checkTopLevelClass(out,
        "com.testEmptyIntArray.R",
        "com.testEmptyIntArray.R$styleable");
    checkInnerClass(out,
        "com.testEmptyIntArray.R$styleable",
        outerClass,
        ImmutableMap.<String, Integer>of(),
        ImmutableMap.<String, List<Integer>>of(
            "ActionMenuView", ImmutableList.<Integer>of()
        ),
        finalFields
    );
  }

  static final Matcher<Throwable> NUMBER_FORMAT_EXCEPTION =
      new BaseMatcher<Throwable>() {
        @Override
        public boolean matches(Object item) {
          if (item instanceof NumberFormatException) {
            return true;
          }
          return false;
        }

        @Override
        public void describeTo(Description description) {
          description.appendText(NumberFormatException.class.toString());
        }
      };

  @Test
  public void corruptIntArraysTrailingComma() throws Exception {
    // Test a few cases of what happens if the R.txt is corrupted. It shouldn't happen unless there
    // is a bug in aapt, or R.txt is manually written the wrong way.
    Path path = createFile("R.txt", new String[] {"int[] styleable ActionMenuView { 1, }"});
    thrown.expectCause(NUMBER_FORMAT_EXCEPTION);
    ResourceSymbols.load(path, MoreExecutors.newDirectExecutorService()).get();
  }

  @Test
  public void corruptIntArraysOmittedMiddle() throws Exception {
    Path path = createFile("R.txt", "int[] styleable ActionMenuView { 1, , 2 }");
    thrown.expectCause(NUMBER_FORMAT_EXCEPTION);
    ResourceSymbols.load(path, MoreExecutors.newDirectExecutorService()).get();
  }

  @Test
  public void binaryDropsLibraryFields() throws Exception {
    boolean finalFields = true;
    // Test what happens if the binary R.txt is not a strict superset of the
    // library R.txt (overrides that drop elements).
    ResourceSymbols symbolValues =
        createSymbolFile("R.txt", "int layout stubbable_activity 0x7f020000");
    ResourceSymbols symbolsInLibrary =
        createSymbolFile(
            "lib.R.txt",
            "int id debug_text_field 0x1",
            "int id debug_text_field2 0x1",
            "int layout stubbable_activity 0x1");
    Path out = temp.resolve("classes");
    Files.createDirectories(out);
    RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), finalFields);
    writer.write("com.foo", symbolsInLibrary.asInitializers());

    Path packageDir = out.resolve("com/foo");
    checkFilesInPackage(packageDir, "R.class", "R$layout.class");
    Class<?> outerClass = checkTopLevelClass(out,
        "com.foo.R",
        "com.foo.R$layout");
    checkInnerClass(out,
        "com.foo.R$layout",
        outerClass,
        ImmutableMap.of("stubbable_activity", 0x7f020000),
        ImmutableMap.<String, List<Integer>>of(),
        finalFields
    );
  }
  
  @Test
  public void writeNothingWithNoResources() throws Exception {
    boolean finalFields = true;
    // Test what happens if the library R.txt has no elements.
    ResourceSymbols symbolValues =
        createSymbolFile("R.txt", "int layout stubbable_activity 0x7f020000");
    ResourceSymbols symbolsInLibrary = createSymbolFile("lib.R.txt");
    Path out = temp.resolve("classes");
    Files.createDirectories(out);
    RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), finalFields);
    writer.write("com.foo", symbolsInLibrary.asInitializers());

    Path packageDir = out.resolve("com/foo");
   
    checkFilesInPackage(packageDir);
  }

  @Test
  public void intArraysFinal() throws Exception {
    checkIntArrays(true);
  }

  @Test
  public void intArraysNonFinal() throws Exception {
    checkIntArrays(false);
  }

  public void checkIntArrays(boolean finalFields) throws Exception {
    ResourceSymbols symbolValues =
        createSymbolFile(
            "R.txt",
            "int attr android_layout 0x010100f2",
            "int attr bar 0x7f010001",
            "int attr baz 0x7f010002",
            "int attr fox 0x7f010003",
            "int attr attr 0x7f010004",
            "int attr another_attr 0x7f010005",
            "int attr zoo 0x7f010006",
            // Test several > 5 elements, clinit must use bytecodes other than iconst_0 to 5.
            "int[] styleable ActionButton { 0x010100f2, 0x7f010001, 0x7f010002, 0x7f010003, "
                + "0x7f010004, 0x7f010005, 0x7f010006 }",
            // The array indices of each attribute.
            "int styleable ActionButton_android_layout 0",
            "int styleable ActionButton_another_attr 5",
            "int styleable ActionButton_attr 4",
            "int styleable ActionButton_bar 1",
            "int styleable ActionButton_baz 2",
            "int styleable ActionButton_fox 3",
            "int styleable ActionButton_zoo 6");
    ResourceSymbols symbolsInLibrary = symbolValues;
    Path out = temp.resolve("classes");
    Files.createDirectories(out);
    RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), finalFields);
    writer.write("com.intArray", symbolsInLibrary.asInitializers());

    Path packageDir = out.resolve("com/intArray");
    checkFilesInPackage(packageDir, "R.class", "R$attr.class", "R$styleable.class");
    Class<?> outerClass = checkTopLevelClass(out,
        "com.intArray.R",
        "com.intArray.R$attr",
        "com.intArray.R$styleable");
    checkInnerClass(out,
        "com.intArray.R$attr",
        outerClass,
        ImmutableMap.<String, Integer>builder()
            .put("android_layout", 0x010100f2)
            .put("bar", 0x7f010001)
            .put("baz", 0x7f010002)
            .put("fox", 0x7f010003)
            .put("attr", 0x7f010004)
            .put("another_attr", 0x7f010005)
            .put("zoo", 0x7f010006)
            .build(),
        ImmutableMap.<String, List<Integer>>of(),
        finalFields
    );
    checkInnerClass(out,
        "com.intArray.R$styleable",
        outerClass,
        ImmutableMap.<String, Integer>builder()
            .put("ActionButton_android_layout", 0)
            .put("ActionButton_bar", 1)
            .put("ActionButton_baz", 2)
            .put("ActionButton_fox", 3)
            .put("ActionButton_attr", 4)
            .put("ActionButton_another_attr", 5)
            .put("ActionButton_zoo", 6)
            .build(),
        ImmutableMap.<String, List<Integer>>of(
            "ActionButton",
            ImmutableList.of(0x010100f2, 0x7f010001, 0x7f010002,
                0x7f010003, 0x7f010004, 0x7f010005, 0x7f010006)
        ),
        finalFields
    );
  }

  @Test
  public void emptyPackage() throws Exception {
    boolean finalFields = true;
    // Make sure we handle an empty package string.
    ResourceSymbols symbolValues = createSymbolFile("R.txt", "int string some_string 0x7f200000");
    ResourceSymbols symbolsInLibrary = symbolValues;
    Path out = temp.resolve("classes");
    Files.createDirectories(out);
    RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), finalFields);
    writer.write("", symbolsInLibrary.asInitializers());

    Path packageDir = out.resolve("");
    checkFilesInPackage(packageDir, "R.class", "R$string.class");
    Class<?> outerClass = checkTopLevelClass(out, "R", "R$string");
    checkInnerClass(
        out,
        "R$string",
        outerClass,
        ImmutableMap.of("some_string", 0x7f200000),
        ImmutableMap.<String, List<Integer>>of(),
        finalFields);
  }

  // Test utilities

  private Path createFile(String name, String... contents) throws IOException {
    Path path = temp.resolve(name);
    Files.createDirectories(path.getParent());
    Files.newOutputStream(path).write(
        Joiner.on("\n").join(contents).getBytes(StandardCharsets.UTF_8));
    return path;
  }

  private ResourceSymbols createSymbolFile(String name, String... contents)
      throws IOException, InterruptedException, ExecutionException {
    Path path = createFile(name, contents);
    ListeningExecutorService executorService = MoreExecutors.newDirectExecutorService();
    ResourceSymbols symbolFile = ResourceSymbols.load(path, executorService).get();
    return symbolFile;
  }

  private static void checkFilesInPackage(Path packageDir, String... expectedFiles)
      throws IOException {
    ImmutableList<String> filesInPackage = ImmutableList
        .copyOf(Iterables.transform(Files.newDirectoryStream(packageDir),
            new Function<Path, String>() {
              @Override
              public String apply(Path path) {
                return path.getFileName().toString();
              }
            }
        ));
    assertThat(filesInPackage).containsExactly((Object[]) expectedFiles);
  }

  private static Class<?> checkTopLevelClass(
      Path baseDir, String expectedClassName, String... expectedInnerClasses) throws Exception {
    try (URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {baseDir.toUri().toURL()})) {
      Class<?> toplevelClass = urlClassLoader.loadClass(expectedClassName);
      assertThat(toplevelClass.getSuperclass()).isEqualTo(Object.class);
      int outerModifiers = toplevelClass.getModifiers();
      assertThat(Modifier.isFinal(outerModifiers)).isTrue();
      assertThat(Modifier.isPublic(outerModifiers)).isTrue();
      ImmutableList.Builder<String> actualClasses = ImmutableList.builder();
      for (Class<?> innerClass : toplevelClass.getClasses()) {
        assertThat(innerClass.getDeclaredClasses()).isEmpty();
        int modifiers = innerClass.getModifiers();
        assertThat(Modifier.isFinal(modifiers)).isTrue();
        assertThat(Modifier.isPublic(modifiers)).isTrue();
        assertThat(Modifier.isStatic(modifiers)).isTrue();
        actualClasses.add(innerClass.getName());
      }
      assertThat(actualClasses.build()).containsExactly((Object[]) expectedInnerClasses);
      return toplevelClass;
    }
  }

  private void checkInnerClass(
      Path baseDir,
      String expectedClassName,
      Class<?> outerClass,
      ImmutableMap<String, Integer> intFields,
      ImmutableMap<String, List<Integer>> intArrayFields,
      boolean areFieldsFinal)
      throws Exception {
    try (URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {baseDir.toUri().toURL()})) {
      Class<?> innerClass = urlClassLoader.loadClass(expectedClassName);
      assertThat(innerClass.getSuperclass()).isEqualTo(Object.class);
      assertThat(innerClass.getEnclosingClass().toString()).isEqualTo(outerClass.toString());
      ImmutableMap.Builder<String, Integer> actualIntFields = ImmutableMap.builder();
      ImmutableMap.Builder<String, List<Integer>> actualIntArrayFields = ImmutableMap.builder();
      for (Field f : innerClass.getFields()) {
        int fieldModifiers = f.getModifiers();
        assertThat(Modifier.isFinal(fieldModifiers)).isEqualTo(areFieldsFinal);
        assertThat(Modifier.isPublic(fieldModifiers)).isTrue();
        assertThat(Modifier.isStatic(fieldModifiers)).isTrue();

        Class<?> fieldType = f.getType();
        if (fieldType.isPrimitive()) {
          assertThat(fieldType).isEqualTo(Integer.TYPE);
          actualIntFields.put(f.getName(), (Integer) f.get(null));
        } else {
          assertThat(fieldType.isArray()).isTrue();
          int[] asArray = (int[]) f.get(null);
          ImmutableList.Builder<Integer> list = ImmutableList.builder();
          for (int i : asArray) {
            list.add(i);
          }
          actualIntArrayFields.put(f.getName(), list.build());
        }
      }
      assertThat(actualIntFields.build()).containsExactlyEntriesIn(intFields);
      assertThat(actualIntArrayFields.build()).containsExactlyEntriesIn(intArrayFields);
    }
  }

}
