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

import com.android.aapt.Resources.Styleable;
import com.android.aapt.Resources.Value;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.android.AndroidCompiledDataDeserializer.ReferenceResolver;
import com.google.devtools.build.android.AndroidDataWritingVisitor;
import com.google.devtools.build.android.AndroidDataWritingVisitor.ValuesResourceDefinition;
import com.google.devtools.build.android.AndroidResourceSymbolSink;
import com.google.devtools.build.android.DataSource;
import com.google.devtools.build.android.FullyQualifiedName;
import com.google.devtools.build.android.XmlResourceValue;
import com.google.devtools.build.android.XmlResourceValues;
import com.google.devtools.build.android.proto.SerializeFormat;
import com.google.devtools.build.android.proto.SerializeFormat.DataValueXml.XmlType;
import java.io.IOException;
import java.io.OutputStream;
import java.util.AbstractMap.SimpleEntry;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import javax.annotation.concurrent.Immutable;

/**
 * Represent an Android styleable resource.
 *
 * <p>Styleable resources are groups of attributes that can be applied to views. They are, for the
 * most part, vaguely documented (http://developer.android.com/training/custom-views/create-view
 * .html#customattr). It is important to note that attributes declared inside
 * &lt;declare-styleable&gt; tags, for example; <code> <declare-styleable name="PieChart"> <attr
 * name="showText" format="boolean" /> </declare-styleable> </code>
 *
 * <p>Can also be seen as: <code> <attr name="showText" format="boolean" /> <declare-styleable
 * name="PieChart"> <attr name="showText"/> </declare-styleable> </code>
 *
 * <p>However, aapt will parse these two cases differently. In order to maintain the expected
 * indexing for the styleable array
 * (http://developer.android.com/reference/android/content/res/Resources.Theme.html
 * #obtainStyledAttributes(android.util.AttributeSet, int[], int, int)) the styleable must track
 * whether the attr is a reference or a definition, as aapt will sort the attributes first by attr
 * format (the absence of format comes first, followed by alphabetical sorting by format, then
 * sorting by declaration order in the source xml.)
 */
@Immutable
public class StyleableXmlResourceValue implements XmlResourceValue {

  static final Function<Map.Entry<FullyQualifiedName, Boolean>, SerializeFormat.DataKey>
      FULLY_QUALIFIED_NAME_TO_DATA_KEY =
          new Function<Map.Entry<FullyQualifiedName, Boolean>, SerializeFormat.DataKey>() {
            @Override
            public SerializeFormat.DataKey apply(Map.Entry<FullyQualifiedName, Boolean> input) {
              return input.getKey().toSerializedBuilder().setReference(input.getValue()).build();
            }
          };

  static final Function<SerializeFormat.DataKey, Map.Entry<FullyQualifiedName, Boolean>>
      DATA_KEY_TO_FULLY_QUALIFIED_NAME =
          new Function<SerializeFormat.DataKey, Map.Entry<FullyQualifiedName, Boolean>>() {
            @Override
            public Map.Entry<FullyQualifiedName, Boolean> apply(SerializeFormat.DataKey input) {
              FullyQualifiedName key = FullyQualifiedName.fromProto(input);
              return new SimpleEntry<FullyQualifiedName, Boolean>(key, input.getReference());
            }
          };

  private final ImmutableMap<FullyQualifiedName, Boolean> attrs;

  private StyleableXmlResourceValue(ImmutableMap<FullyQualifiedName, Boolean> attrs) {
    this.attrs = attrs;
  }

  @VisibleForTesting
  public static XmlResourceValue createAllAttrAsReferences(FullyQualifiedName... attrNames) {
    return of(createAttrDefinitionMap(attrNames, Boolean.FALSE));
  }

  private static Map<FullyQualifiedName, Boolean> createAttrDefinitionMap(
      FullyQualifiedName[] attrNames, Boolean definitionType) {
    ImmutableMap.Builder<FullyQualifiedName, Boolean> builder = ImmutableMap.builder();
    for (FullyQualifiedName attrName : attrNames) {
      builder.put(attrName, definitionType);
    }
    return builder.build();
  }

  @VisibleForTesting
  public static XmlResourceValue createAllAttrAsDefinitions(FullyQualifiedName... attrNames) {
    return of(createAttrDefinitionMap(attrNames, Boolean.TRUE));
  }

  public static XmlResourceValue of(Map<FullyQualifiedName, Boolean> attrs) {
    return new StyleableXmlResourceValue(ImmutableMap.copyOf(attrs));
  }

  @Override
  public void write(
      FullyQualifiedName key, DataSource source, AndroidDataWritingVisitor mergedDataWriter) {
    ValuesResourceDefinition definition =
        mergedDataWriter
            .define(key)
            .derivedFrom(source)
            .startTag("declare-styleable")
            .named(key)
            .closeTag();
    for (Map.Entry<FullyQualifiedName, Boolean> entry : attrs.entrySet()) {
      if (entry.getValue().booleanValue()) {
        // Move the attr definition to this styleable.
        definition = definition.adopt(entry.getKey());
      } else {
        // Make a reference to the attr.
        definition =
            definition
                .startTag("attr")
                .attribute("name")
                .setTo(entry.getKey())
                .closeUnaryTag()
                .addCharactersOf("\n");
      }
    }
    definition.endTag().save();
  }

  @Override
  public void writeResourceToClass(FullyQualifiedName key, AndroidResourceSymbolSink sink) {
    sink.acceptStyleableResource(key, attrs);
  }

  @Override
  public int serializeTo(int sourceId, Namespaces namespaces, OutputStream output)
      throws IOException {
    return XmlResourceValues.serializeProtoDataValue(
        output,
        XmlResourceValues.newSerializableDataValueBuilder(sourceId)
            .setXmlValue(
                SerializeFormat.DataValueXml.newBuilder()
                    .setType(XmlType.STYLEABLE)
                    .putAllNamespace(namespaces.asMap())
                    .addAllReferences(
                        Iterables.transform(attrs.entrySet(), FULLY_QUALIFIED_NAME_TO_DATA_KEY))));
  }

  public static XmlResourceValue from(SerializeFormat.DataValueXml proto) {
    return of(
        ImmutableMap.copyOf(
            Iterables.transform(proto.getReferencesList(), DATA_KEY_TO_FULLY_QUALIFIED_NAME)));
  }

  public static XmlResourceValue from(Value proto, ReferenceResolver packageResolver) {
    Map<FullyQualifiedName, Boolean> attributes = new HashMap<>();

    Styleable styleable = proto.getCompoundValue().getStyleable();
    for (Styleable.Entry entry : styleable.getEntryList()) {
      final FullyQualifiedName reference = packageResolver.parse(entry.getAttr().getName());
      final boolean shouldInline = packageResolver.shouldInline(reference);
      attributes.put(reference, shouldInline);
      if (shouldInline) {
        packageResolver.markInlined(reference);
      }
    }

    return of(ImmutableMap.copyOf(attributes));
  }

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

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof StyleableXmlResourceValue)) {
      return false;
    }
    StyleableXmlResourceValue other = (StyleableXmlResourceValue) obj;
    return Objects.equals(attrs, other.attrs);
  }

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

  /**
   * Combines this instance with another {@link StyleableXmlResourceValue}.
   *
   * <p>Defining two Styleables (undocumented in the official Android Docs) with the same {@link
   * FullyQualifiedName} results in a single Styleable containing a union of all the attribute
   * references.
   *
   * @param value Another {@link StyleableXmlResourceValue} with the same {@link
   *     FullyQualifiedName}.
   * @return {@link StyleableXmlResourceValue} containing a sorted union of the attribute
   *     references.
   * @throws IllegalArgumentException if value is not an {@link StyleableXmlResourceValue}.
   */
  @Override
  public XmlResourceValue combineWith(XmlResourceValue value) {
    if (!(value instanceof StyleableXmlResourceValue)) {
      throw new IllegalArgumentException(value + "is not combinable with " + this);
    }
    StyleableXmlResourceValue styleable = (StyleableXmlResourceValue) value;
    Map<FullyQualifiedName, Boolean> combined = new LinkedHashMap<>();
    combined.putAll(attrs);
    for (Map.Entry<FullyQualifiedName, Boolean> attr : styleable.attrs.entrySet()) {
      if (combined.containsKey(attr.getKey())) {
        // if either attr is defined in the styleable, the attr will be defined in the styleable.
        if (attr.getValue() || combined.get(attr.getKey())) {
          combined.put(attr.getKey(), Boolean.TRUE);
        } else {
          combined.put(attr.getKey(), Boolean.FALSE);
        }
      } else {
        combined.put(attr.getKey(), attr.getValue());
      }
    }
    return of(combined);
  }

  @Override
  public int compareMergePriorityTo(XmlResourceValue value) {
    return 0;
  }

  @Override
  public String asConflictStringWith(DataSource source) {
    return source.asConflictString();
  }
}
