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

import static com.google.devtools.build.android.ParsedAndroidDataBuilder.file;
import static com.google.devtools.build.android.ParsedAndroidDataBuilder.xml;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.jimfs.Jimfs;
import com.google.common.truth.Truth;
import com.google.devtools.build.android.xml.IdXmlResourceValue;
import com.google.devtools.build.android.xml.ResourcesAttribute;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for the AndroidDataSerializer and AndroidDataDeserializer. */
@RunWith(JUnit4.class)
public class AndroidDataSerializerAndDeserializerTest {

  private FileSystem fs;
  private FullyQualifiedName.Factory fqnFactory;
  private Path source;
  private Path manifest;

  @Before
  public void createCleanEnvironment() throws Exception {
    fs = Jimfs.newFileSystem();
    fqnFactory = FullyQualifiedName.Factory.from(ImmutableList.<String>of());
    source = Files.createDirectory(fs.getPath("source"));
    manifest = Files.createFile(source.resolve("AndroidManifest.xml"));
  }

  @Test
  public void serializeAssets() throws Exception {
    Path binaryPath = fs.getPath("out.bin");
    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    UnwrittenMergedAndroidData expected =
        UnwrittenMergedAndroidData.of(
            manifest,
            ParsedAndroidDataBuilder.buildOn(source)
                .assets(file().source("hunting/of/the/boojum"))
                .build(),
            ParsedAndroidDataBuilder.empty());
    expected.serializeTo(serializer);
    serializer.flushTo(binaryPath);

    AndroidDataDeserializer deserializer = AndroidParsedDataDeserializer.create();
    TestMapConsumer<DataAsset> assets = TestMapConsumer.ofAssets();
    deserializer.read(binaryPath, KeyValueConsumers.of(null, null, assets));
    Truth.assertThat(assets).isEqualTo(expected.getPrimary().getAssets());
  }

  @Test
  public void serializeCombiningResource() throws Exception {
    Path binaryPath = fs.getPath("out.bin");
    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    UnwrittenMergedAndroidData expected =
        UnwrittenMergedAndroidData.of(
            manifest,
            ParsedAndroidDataBuilder.buildOn(source, fqnFactory)
                .combining(
                    xml("id/snark").source("values/ids.xml").value(IdXmlResourceValue.of()))
                .build(),
            ParsedAndroidDataBuilder.empty());
    expected.serializeTo(serializer);
    serializer.flushTo(binaryPath);

    AndroidDataDeserializer deserializer = AndroidParsedDataDeserializer.create();
    TestMapConsumer<DataResource> resources = TestMapConsumer.ofResources();
    deserializer.read(
        binaryPath,
        KeyValueConsumers.of(
            null, // overwriting
            resources, // combining
            null // assets
            ));
    Truth.assertThat(resources).isEqualTo(expected.getPrimary().getCombiningResources());
  }

  @Test
  public void serializeOverwritingResource() throws Exception {
    Path binaryPath = fs.getPath("out.bin");
    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    UnwrittenMergedAndroidData expected =
        UnwrittenMergedAndroidData.of(
            manifest,
            ParsedAndroidDataBuilder.buildOn(source, fqnFactory)
                .overwritable(file("layout/banker").source("layout/banker.xml"))
                .build(),
            ParsedAndroidDataBuilder.empty());
    expected.serializeTo(serializer);
    serializer.flushTo(binaryPath);

    AndroidDataDeserializer deserializer = AndroidParsedDataDeserializer.create();
    TestMapConsumer<DataResource> resources = TestMapConsumer.ofResources();
    deserializer.read(
        binaryPath,
        KeyValueConsumers.of(
            resources, // overwriting
            null, // combining
            null // assets
            ));
    Truth.assertThat(resources).isEqualTo(expected.getPrimary().getOverwritingResources());
  }

  @Test
  public void serializeFileWithIds() throws Exception {
    Path binaryPath = fs.getPath("out.bin");
    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    ParsedAndroidData direct =
        AndroidDataBuilder.of(source)
            .addResource(
                "layout/some_layout.xml",
                AndroidDataBuilder.ResourceType.LAYOUT,
                "<TextView android:id=\"@+id/MyTextView\"",
                "          android:text=\"@string/walrus\"",
                "          android:layout_width=\"wrap_content\"",
                "          android:layout_height=\"wrap_content\" />")
            // Test what happens if a user accidentally uses the same ID in multiple layouts too.
            .addResource(
                "layout/another_layout.xml",
                AndroidDataBuilder.ResourceType.LAYOUT,
                "<TextView android:id=\"@+id/MyTextView\"",
                "          android:text=\"@string/walrus\"",
                "          android:layout_width=\"wrap_content\"",
                "          android:layout_height=\"wrap_content\" />")
            // Also check what happens if a value XML file also contains the same ID.
            .addResource(
                "values/ids.xml",
                AndroidDataBuilder.ResourceType.VALUE,
                "<item name=\"MyTextView\" type=\"id\"/>",
                "<item name=\"OtherId\" type=\"id\"/>")
            .addResource(
                "values/strings.xml",
                AndroidDataBuilder.ResourceType.VALUE,
                "<string name=\"walrus\">I has a bucket</string>")
            .createManifest("AndroidManifest.xml", "com.carroll.lewis", "")
            .buildParsed();
    UnwrittenMergedAndroidData expected =
        UnwrittenMergedAndroidData.of(
            manifest,
            direct,
            ParsedAndroidDataBuilder.empty());
    expected.serializeTo(serializer);
    serializer.flushTo(binaryPath);

    AndroidDataDeserializer deserializer = AndroidParsedDataDeserializer.create();
    TestMapConsumer<DataResource> overwriting = TestMapConsumer.ofResources();
    TestMapConsumer<DataResource> combining = TestMapConsumer.ofResources();
    deserializer.read(
        binaryPath,
        KeyValueConsumers.of(
            overwriting,
            combining,
            null // assets
        ));
    Truth.assertThat(overwriting).isEqualTo(expected.getPrimary().getOverwritingResources());
    Truth.assertThat(combining).isEqualTo(expected.getPrimary().getCombiningResources());
  }

  @Test
  public void serialize() throws Exception {
    Path binaryPath = fs.getPath("out.bin");
    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    UnwrittenMergedAndroidData expected =
        UnwrittenMergedAndroidData.of(
            manifest,
            ParsedAndroidDataBuilder.buildOn(source, fqnFactory)
                .overwritable(
                    file("layout/banker").source("layout/banker.xml"),
                    xml("<resources>/foo").source("values/ids.xml")
                        .value(ResourcesAttribute.of(
                            fqnFactory.parse("<resources>/foo"), "foo", "fooVal")))
                .combining(
                    xml("id/snark").source("values/ids.xml").value(IdXmlResourceValue.of()))
                .assets(file().source("hunting/of/the/boojum"))
                .build(),
            ParsedAndroidDataBuilder.buildOn(source, fqnFactory)
                .overwritable(file("layout/butcher").source("layout/butcher.xml"))
                .combining(
                    xml("id/snark").source("values/ids.xml").value(IdXmlResourceValue.of()))
                .assets(file().source("hunting/of/the/snark"))
                .build());
    expected.serializeTo(serializer);
    serializer.flushTo(binaryPath);

    KeyValueConsumers primary =
        KeyValueConsumers.of(
            TestMapConsumer.ofResources(), // overwriting
            TestMapConsumer.ofResources(), // combining
            TestMapConsumer.ofAssets() // assets
            );

    AndroidDataDeserializer deserializer = AndroidParsedDataDeserializer.create();
    deserializer.read(binaryPath, primary);
    Truth.assertThat(primary.overwritingConsumer)
        .isEqualTo(expected.getPrimary().getOverwritingResources());
    Truth.assertThat(primary.combiningConsumer)
        .isEqualTo(expected.getPrimary().getCombiningResources());
    Truth.assertThat(primary.assetConsumer).isEqualTo(expected.getPrimary().getAssets());
  }

  @Test
  public void testDeserializeMissing() throws Exception {
    Path binaryPath = fs.getPath("out.bin");
    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    UnwrittenMergedAndroidData expected =
        UnwrittenMergedAndroidData.of(
            manifest,
            ParsedAndroidDataBuilder.buildOn(source, fqnFactory)
                .overwritable(
                    file("layout/banker").source("layout/banker.xml"),
                    xml("<resources>/foo").source("values/ids.xml")
                        .value(ResourcesAttribute.of(
                            fqnFactory.parse("<resources>/foo"), "foo", "fooVal")))
                .combining(
                    xml("id/snark").source("values/ids.xml").value(IdXmlResourceValue.of()))
                .assets(file().source("hunting/of/the/boojum"))
                .build(),
            ParsedAndroidDataBuilder.buildOn(source, fqnFactory)
                .overwritable(file("layout/butcher").source("layout/butcher.xml"))
                .combining(
                    xml("id/snark").source("values/ids.xml").value(IdXmlResourceValue.of()))
                .assets(file().source("hunting/of/the/snark"))
                .build());
    expected.serializeTo(serializer);
    serializer.flushTo(binaryPath);

    AndroidDataDeserializer deserializer =
        AndroidParsedDataDeserializer.withFilteredResources(
            ImmutableList.of("the/boojum", "values/ids.xml", "layout/banker.xml"));

    KeyValueConsumers primary =
        KeyValueConsumers.of(
            TestMapConsumer.ofResources(), // overwriting
            TestMapConsumer.ofResources(), // combining
            null // assets
            );

    deserializer.read(binaryPath, primary);
    Truth.assertThat(primary.overwritingConsumer).isEqualTo(Collections.emptyMap());
    Truth.assertThat(primary.combiningConsumer).isEqualTo(Collections.emptyMap());
  }

  private static class TestMapConsumer<T extends DataValue>
      implements ParsedAndroidData.KeyValueConsumer<DataKey, T>, Map<DataKey, T> {

    Map<DataKey, T> target;

    static TestMapConsumer<DataAsset> ofAssets() {
      return new TestMapConsumer<>(new HashMap<DataKey, DataAsset>());
    }

    static TestMapConsumer<DataResource> ofResources() {
      return new TestMapConsumer<>(new HashMap<DataKey, DataResource>());
    }

    public TestMapConsumer(Map<DataKey, T> target) {
      this.target = target;
    }

    @Override
    public void accept(DataKey key, T value) {
      target.put(key, value);
    }

    @Override
    public int size() {
      return target.size();
    }

    @Override
    public boolean isEmpty() {
      return target.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
      return target.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
      return target.containsValue(value);
    }

    @Override
    public T get(Object key) {
      return target.get(key);
    }

    @Override
    public T put(DataKey key, T value) {
      return target.put(key, value);
    }

    @Override
    public T remove(Object key) {
      return target.remove(key);
    }

    @Override
    public void putAll(Map<? extends DataKey, ? extends T> m) {
      target.putAll(m);
    }

    @Override
    public void clear() {
      target.clear();
    }

    @Override
    public Set<DataKey> keySet() {
      return target.keySet();
    }

    @Override
    public Collection<T> values() {
      return target.values();
    }

    @Override
    public Set<java.util.Map.Entry<DataKey, T>> entrySet() {
      return target.entrySet();
    }

    @Override
    public boolean equals(Object o) {
      return target.equals(o);
    }

    @Override
    public int hashCode() {
      return target.hashCode();
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(this).add("target", target).toString();
    }
  }
}
