// Copyright 2014 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.lib.packages;

import static com.google.devtools.build.lib.packages.BuildType.DISTRIBUTIONS;
import static com.google.devtools.build.lib.packages.BuildType.GENQUERY_SCOPE_TYPE;
import static com.google.devtools.build.lib.packages.BuildType.GENQUERY_SCOPE_TYPE_LIST;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_DICT_UNARY;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_KEYED_STRING_DICT;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.BuildType.LICENSE;
import static com.google.devtools.build.lib.packages.BuildType.NODEP_LABEL;
import static com.google.devtools.build.lib.packages.BuildType.NODEP_LABEL_LIST;
import static com.google.devtools.build.lib.packages.BuildType.OUTPUT;
import static com.google.devtools.build.lib.packages.BuildType.OUTPUT_LIST;
import static com.google.devtools.build.lib.packages.BuildType.TRISTATE;
import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
import static com.google.devtools.build.lib.packages.Type.INTEGER;
import static com.google.devtools.build.lib.packages.Type.INTEGER_LIST;
import static com.google.devtools.build.lib.packages.Type.STRING;
import static com.google.devtools.build.lib.packages.Type.STRING_DICT;
import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
import static com.google.devtools.build.lib.packages.Type.STRING_LIST_DICT;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.BuildType.Selector;
import com.google.devtools.build.lib.packages.BuildType.SelectorList;
import com.google.devtools.build.lib.query2.proto.proto2api.Build;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.Attribute.Discriminator;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.Attribute.SelectorEntry;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.Attribute.Tristate;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.LabelDictUnaryEntry;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.LabelKeyedStringDictEntry;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.StringDictEntry;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.StringListDictEntry;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import net.starlark.java.eval.StarlarkInt;

/** Common utilities for serializing {@link Attribute}s as protocol buffers. */
public class AttributeFormatter {

  private static final ImmutableSet<Type<?>> depTypes =
      ImmutableSet.of(
          STRING,
          LABEL,
          OUTPUT,
          STRING_LIST,
          LABEL_LIST,
          LABEL_DICT_UNARY,
          LABEL_KEYED_STRING_DICT,
          OUTPUT_LIST,
          DISTRIBUTIONS);

  private static final ImmutableSet<Type<?>> noDepTypes =
      ImmutableSet.of(NODEP_LABEL_LIST, NODEP_LABEL);

  private AttributeFormatter() {}

  /**
   * Convert attribute value to proto representation.
   *
   * <p>If {@code value} is null, only the {@code name}, {@code explicitlySpecified}, {@code nodep}
   * (if applicable), and {@code type} fields will be included in the proto message.
   *
   * <p>If {@param encodeBooleanAndTriStateAsIntegerAndString} is true then boolean and tristate
   * values are also encoded as integers and strings.
   */
  public static Build.Attribute getAttributeProto(
      Attribute attr,
      @Nullable Object value,
      boolean explicitlySpecified,
      boolean encodeBooleanAndTriStateAsIntegerAndString) {
    return getAttributeProto(
        attr.getName(),
        attr.getType(),
        value,
        explicitlySpecified,
        encodeBooleanAndTriStateAsIntegerAndString);
  }

  private static Build.Attribute getAttributeProto(
      String name,
      Type<?> type,
      @Nullable Object value,
      boolean explicitlySpecified,
      boolean encodeBooleanAndTriStateAsIntegerAndString) {
    Build.Attribute.Builder attrPb = Build.Attribute.newBuilder();
    attrPb.setName(name);
    attrPb.setExplicitlySpecified(explicitlySpecified);
    maybeSetNoDep(type, attrPb);

    if (value instanceof SelectorList<?>) {
      attrPb.setType(Discriminator.SELECTOR_LIST);
      writeSelectorListToBuilder(attrPb, type, (SelectorList<?>) value);
    } else {
      attrPb.setType(ProtoUtils.getDiscriminatorFromType(type));
      if (value != null) {
        AttributeBuilderAdapter adapter =
            new AttributeBuilderAdapter(attrPb, encodeBooleanAndTriStateAsIntegerAndString);
        writeAttributeValueToBuilder(adapter, type, value);
      }
    }

    return attrPb.build();
  }

  private static void maybeSetNoDep(Type<?> type, Build.Attribute.Builder attrPb) {
    if (depTypes.contains(type)) {
      attrPb.setNodep(false);
    } else if (noDepTypes.contains(type)) {
      attrPb.setNodep(true);
    }
  }

  private static void writeSelectorListToBuilder(
      Build.Attribute.Builder attrPb, Type<?> type, SelectorList<?> selectorList) {
    Build.Attribute.SelectorList.Builder selectorListBuilder =
        Build.Attribute.SelectorList.newBuilder();
    selectorListBuilder.setType(ProtoUtils.getDiscriminatorFromType(type));
    for (Selector<?> selector : selectorList.getSelectors()) {
      Build.Attribute.Selector.Builder selectorBuilder =
          Build.Attribute.Selector.newBuilder()
              .setNoMatchError(selector.getNoMatchError())
              .setHasDefaultValue(selector.hasDefault());

      // Note that the order of entries returned by selector.getEntries is stable. The map's
      // entries' order is preserved from the fact that Starlark dictionary entry order is stable
      // (it's determined by insertion order).
      for (Map.Entry<Label, ?> entry : selector.getEntries().entrySet()) {
        Label condition = entry.getKey();
        SelectorEntry.Builder selectorEntryBuilder =
            SelectorEntry.newBuilder()
                .setLabel(condition.toString())
                .setIsDefaultValue(!selector.isValueSet(condition));

        Object conditionValue = entry.getValue();
        if (conditionValue != null) {
          writeAttributeValueToBuilder(
              new SelectorEntryBuilderAdapter(selectorEntryBuilder), type, conditionValue);
        }
        selectorBuilder.addEntries(selectorEntryBuilder);
      }
      selectorListBuilder.addElements(selectorBuilder);
    }
    attrPb.setSelectorList(selectorListBuilder);
  }

  /**
   * Set the appropriate type and value. Since string and string list store values for multiple
   * types, use the toString() method on the objects instead of casting them.
   */
  private static void writeAttributeValueToBuilder(
      AttributeValueBuilderAdapter builder, Type<?> type, Object value) {
    if (type == INTEGER) {
      builder.setIntValue(((StarlarkInt) value).toIntUnchecked());
    } else if (type == STRING
        || type == LABEL
        || type == NODEP_LABEL
        || type == OUTPUT
        || type == GENQUERY_SCOPE_TYPE) {

      builder.setStringValue(value.toString());
    } else if (type == STRING_LIST
        || type == LABEL_LIST
        || type == NODEP_LABEL_LIST
        || type == OUTPUT_LIST
        || type == DISTRIBUTIONS
        || type == GENQUERY_SCOPE_TYPE_LIST) {
      for (Object entry : (Collection<?>) value) {
        builder.addStringListValue(entry.toString());
      }
    } else if (type == INTEGER_LIST) {
      for (Object elem : (Collection<?>) value) {
        builder.addIntListValue(((StarlarkInt) elem).toIntUnchecked());
      }
    } else if (type == BOOLEAN) {
      builder.setBooleanValue((Boolean) value);
    } else if (type == TRISTATE) {
      builder.setTristateValue(triStateToProto((TriState) value));
    } else if (type == LICENSE) {
      License license = (License) value;
      Build.License.Builder licensePb = Build.License.newBuilder();
      for (License.LicenseType licenseType : license.getLicenseTypes()) {
        licensePb.addLicenseType(licenseType.toString());
      }
      for (Label exception : license.getExceptions()) {
        licensePb.addException(exception.toString());
      }
      builder.setLicense(licensePb);
    } else if (type == STRING_DICT) {
      @SuppressWarnings("unchecked")
      Map<String, String> dict = (Map<String, String>) value;
      for (Map.Entry<String, String> keyValueList : dict.entrySet()) {
        StringDictEntry.Builder entry =
            StringDictEntry.newBuilder()
                .setKey(keyValueList.getKey())
                .setValue(keyValueList.getValue());
        builder.addStringDictValue(entry);
      }
    } else if (type == STRING_LIST_DICT) {
      @SuppressWarnings("unchecked")
      Map<String, List<String>> dict = (Map<String, List<String>>) value;
      for (Map.Entry<String, List<String>> dictEntry : dict.entrySet()) {
        StringListDictEntry.Builder entry =
            StringListDictEntry.newBuilder().setKey(dictEntry.getKey());
        for (Object dictEntryValue : dictEntry.getValue()) {
          entry.addValue(dictEntryValue.toString());
        }
        builder.addStringListDictValue(entry);
      }
    } else if (type == LABEL_DICT_UNARY) {
      @SuppressWarnings("unchecked")
      Map<String, Label> dict = (Map<String, Label>) value;
      for (Map.Entry<String, Label> dictEntry : dict.entrySet()) {
        LabelDictUnaryEntry.Builder entry =
            LabelDictUnaryEntry.newBuilder()
                .setKey(dictEntry.getKey())
                .setValue(dictEntry.getValue().toString());
        builder.addLabelDictUnaryValue(entry);
      }
    } else if (type == LABEL_KEYED_STRING_DICT) {
      @SuppressWarnings("unchecked")
      Map<Label, String> dict = (Map<Label, String>) value;
      for (Map.Entry<Label, String> dictEntry : dict.entrySet()) {
        LabelKeyedStringDictEntry.Builder entry =
            LabelKeyedStringDictEntry.newBuilder()
                .setKey(dictEntry.getKey().toString())
                .setValue(dictEntry.getValue());
        builder.addLabelKeyedStringDictValue(entry);
      }
    } else {
      throw new AssertionError("Unknown type: " + type);
    }
  }

  private static Tristate triStateToProto(TriState value) {
    switch (value) {
      case AUTO:
        return Tristate.AUTO;
      case NO:
        return Tristate.NO;
      case YES:
        return Tristate.YES;
      default:
        throw new AssertionError("Expected AUTO/NO/YES to cover all possible cases");
    }
  }

  /**
   * An adapter used by {@link #writeAttributeValueToBuilder} in order to reuse the same code for
   * writing to both {@link Build.Attribute.Builder} and {@link SelectorEntry.Builder} objects.
   */
  private interface AttributeValueBuilderAdapter {

    void addStringListValue(String s);

    void addLabelDictUnaryValue(LabelDictUnaryEntry.Builder builder);

    void addLabelKeyedStringDictValue(LabelKeyedStringDictEntry.Builder builder);

    void addIntListValue(int i);

    void addStringDictValue(StringDictEntry.Builder builder);

    void addStringListDictValue(StringListDictEntry.Builder builder);

    void setBooleanValue(boolean b);

    void setIntValue(int i);

    void setLicense(Build.License.Builder builder);

    void setStringValue(String s);

    void setTristateValue(Tristate tristate);
  }

  /**
   * An {@link AttributeValueBuilderAdapter} which writes to a {@link Build.Attribute.Builder}.
   *
   * <p>If {@param encodeBooleanAndTriStateAsIntegerAndString} is {@code true}, then {@link Boolean}
   * and {@link TriState} attribute values also write to the integer and string fields. This offers
   * backwards compatibility to clients that expect attribute values of those types.
   */
  private static class AttributeBuilderAdapter implements AttributeValueBuilderAdapter {
    private final boolean encodeBooleanAndTriStateAsIntegerAndString;
    private final Build.Attribute.Builder attributeBuilder;

    private AttributeBuilderAdapter(
        Build.Attribute.Builder attributeBuilder,
        boolean encodeBooleanAndTriStateAsIntegerAndString) {
      this.attributeBuilder = Preconditions.checkNotNull(attributeBuilder);
      this.encodeBooleanAndTriStateAsIntegerAndString = encodeBooleanAndTriStateAsIntegerAndString;
    }

    @Override
    public void addStringListValue(String s) {
      attributeBuilder.addStringListValue(s);
    }

    @Override
    public void addLabelDictUnaryValue(LabelDictUnaryEntry.Builder builder) {
      attributeBuilder.addLabelDictUnaryValue(builder);
    }

    @Override
    public void addLabelKeyedStringDictValue(LabelKeyedStringDictEntry.Builder builder) {
      attributeBuilder.addLabelKeyedStringDictValue(builder);
    }

    @Override
    public void addIntListValue(int i) {
      attributeBuilder.addIntListValue(i);
    }

    @Override
    public void addStringDictValue(StringDictEntry.Builder builder) {
      attributeBuilder.addStringDictValue(builder);
    }

    @Override
    public void addStringListDictValue(StringListDictEntry.Builder builder) {
      attributeBuilder.addStringListDictValue(builder);
    }

    @Override
    public void setBooleanValue(boolean b) {
      if (b) {
        attributeBuilder.setBooleanValue(true);
        if (encodeBooleanAndTriStateAsIntegerAndString) {
          attributeBuilder.setStringValue("true");
          attributeBuilder.setIntValue(1);
        }
      } else {
        attributeBuilder.setBooleanValue(false);
        if (encodeBooleanAndTriStateAsIntegerAndString) {
          attributeBuilder.setStringValue("false");
          attributeBuilder.setIntValue(0);
        }
      }
    }

    @Override
    public void setIntValue(int i) {
      attributeBuilder.setIntValue(i);
    }

    @Override
    public void setLicense(Build.License.Builder builder) {
      attributeBuilder.setLicense(builder);
    }

    @Override
    public void setStringValue(String s) {
      attributeBuilder.setStringValue(s);
    }

    @Override
    public void setTristateValue(Tristate tristate) {
      switch (tristate) {
        case AUTO:
          attributeBuilder.setTristateValue(Tristate.AUTO);
          if (encodeBooleanAndTriStateAsIntegerAndString) {
            attributeBuilder.setIntValue(-1);
            attributeBuilder.setStringValue("auto");
          }
          break;
        case NO:
          attributeBuilder.setTristateValue(Tristate.NO);
          if (encodeBooleanAndTriStateAsIntegerAndString) {
            attributeBuilder.setIntValue(0);
            attributeBuilder.setStringValue("no");
          }
          break;
        case YES:
          attributeBuilder.setTristateValue(Tristate.YES);
          if (encodeBooleanAndTriStateAsIntegerAndString) {
            attributeBuilder.setIntValue(1);
            attributeBuilder.setStringValue("yes");
          }
          break;
        default:
          throw new AssertionError("Expected AUTO/NO/YES to cover all possible cases");
      }
    }
  }

  /**
   * An {@link AttributeValueBuilderAdapter} which writes to a {@link SelectorEntry.Builder}.
   *
   * <p>Note that there is no {@code encodeBooleanAndTriStateAsIntegerAndString} parameter needed
   * here. This is because the clients that expect those alternate encodings of boolean and tristate
   * attribute values do not support {@link SelectorList} values. When providing output to those
   * clients, we compute the set of possible attribute values (expanding {@link SelectorList}
   * values, evaluating computed defaults, and flattening collections of collections; see {@link
   * com.google.devtools.build.lib.packages.AggregatingAttributeMapper#visitAttribute}).
   */
  private static class SelectorEntryBuilderAdapter implements AttributeValueBuilderAdapter {
    private final SelectorEntry.Builder selectorEntryBuilder;

    private SelectorEntryBuilderAdapter(SelectorEntry.Builder selectorEntryBuilder) {
      this.selectorEntryBuilder = Preconditions.checkNotNull(selectorEntryBuilder);
    }

    @Override
    public void addStringListValue(String s) {
      selectorEntryBuilder.addStringListValue(s);
    }

    @Override
    public void addLabelDictUnaryValue(LabelDictUnaryEntry.Builder builder) {
      selectorEntryBuilder.addLabelDictUnaryValue(builder);
    }

    @Override
    public void addLabelKeyedStringDictValue(LabelKeyedStringDictEntry.Builder builder) {
      selectorEntryBuilder.addLabelKeyedStringDictValue(builder);
    }

    @Override
    public void addIntListValue(int i) {
      selectorEntryBuilder.addIntListValue(i);
    }

    @Override
    public void addStringDictValue(StringDictEntry.Builder builder) {
      selectorEntryBuilder.addStringDictValue(builder);
    }

    @Override
    public void addStringListDictValue(StringListDictEntry.Builder builder) {
      selectorEntryBuilder.addStringListDictValue(builder);
    }

    @Override
    public void setBooleanValue(boolean b) {
      selectorEntryBuilder.setBooleanValue(b);
    }

    @Override
    public void setIntValue(int i) {
      selectorEntryBuilder.setIntValue(i);
    }

    @Override
    public void setLicense(Build.License.Builder builder) {
      selectorEntryBuilder.setLicense(builder);
    }

    @Override
    public void setStringValue(String s) {
      selectorEntryBuilder.setStringValue(s);
    }

    @Override
    public void setTristateValue(Tristate tristate) {
      selectorEntryBuilder.setTristateValue(tristate);
    }
  }
}
