// 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 javax.annotation.Nullable;

/**
 * Provides attribute setting and retrieval for a Rule. Encapsulating attribute access here means it
 * can be passed around independently of the Rule itself. In particular, it can be consumed by
 * independent {@link AttributeMap} instances that can apply varying kinds of logic for determining
 * the "value" of an attribute. For example, a configurable attribute's "value" may be a { config
 * --> value } dictionary or a configuration-bound lookup on that dictionary, depending on the
 * context in which it's requested.
 *
 * <p>This class provides the lowest-level access to attribute information. It is *not* intended to
 * be a robust public interface, but rather just an input to {@link AttributeMap} instances. Use
 * those instances for all domain-level attribute access.
 */
// TODO(adonovan): eliminate this class. 99% of all external calls to its methods are of the form
// rule.getAttributeContainer().foo(), so it's just needless indirection for the caller, and
// needless indirection in the representation. Instead, make Rule implement an interface with the
// two methods getAttr and isAttributeValueExplicitlySpecified; it already has those methods.
// The only time the AttributeContainer needs to be distinct from the Rule itself is in the
// WorkspaceFactory.setParent hack. Perhaps we can eliminate that?
public final class AttributeContainer {

  private final RuleClass ruleClass;

  // Attribute values, keyed by attribute index.
  private final Object[] attributeValues;

  // Holds a list of attribute indices (+1, to make them nonzero).
  // The first byte gives the length of the list.
  // The list records which attributes were set explicitly in the BUILD file.
  // The list may be padded with zeros at the end.
  private byte[] state;

  /** Creates a container for a rule of the given rule class. */
  AttributeContainer(RuleClass ruleClass) {
    int n = ruleClass.getAttributeCount();
    if (n > 254) {
      // We reserve the zero byte as a hole/sentinel inside state[].
      // If you hit this limit, replace byte with char and remove the masking with 0xff.
      throw new AssertionError("can't pack " + n + " rule indices into bytes");
    }
    this.ruleClass = ruleClass;
    this.attributeValues = new Object[n];
    this.state = EMPTY_STATE;
  }

  private static final byte[] EMPTY_STATE = {0};

  /**
   * Returns an attribute value by name, or null on no match.
   */
  @Nullable
  public Object getAttr(String attrName) {
    Integer idx = ruleClass.getAttributeIndex(attrName);
    return idx != null ? attributeValues[idx] : null;
  }

  /** See {@link #isAttributeValueExplicitlySpecified(String)}. */
  boolean isAttributeValueExplicitlySpecified(Attribute attribute) {
    return isAttributeValueExplicitlySpecified(attribute.getName());
  }

  /**
   * Returns true iff the value of the specified attribute is explicitly set in the BUILD file. This
   * returns true also if the value explicitly specified in the BUILD file is the same as the
   * attribute's default value. In addition, this method return false if the rule has no attribute
   * with the given name.
   */
  public boolean isAttributeValueExplicitlySpecified(String attributeName) {
    Integer idx = ruleClass.getAttributeIndex(attributeName);
    return idx != null && getExplicit(idx);
  }

 /**
  * Returns the number of elements of state[] currently used to store
  * indices of "explicitly set" attributes.
  */
  private int explicitCount() {
    return 0xff & state[0];
  }

  private boolean getExplicit(int index) {
    int n = explicitCount();
    for (int i = 1; i <= n; ++i) {
      if ((0xff & state[i]) == index + 1) {
        return true;
      }
    }
    return false;
  }

  private void setExplicit(int index) {
    if (getExplicit(index)) {
      return;
    }
    ensureSpace();
    int n = explicitCount() + 1;
    state[0] = (byte) n;
    state[n] = (byte) (index + 1);
  }

  /**
   * Ensures that the state[n] byte is equal to the sentinel value 0, so there is room for another
   * attribute's explicit bit to be set.
   */
  private void ensureSpace() {
    int n = explicitCount() + 1;
    if (n < state.length && state[n] == 0) {
      return;
    }
    // Grow up to the next multiple of eight bytes, as the object will be
    // aligned to eight bytes anyway.  Pad with zeros at the end.
    byte[] newState = new byte[(state.length | 7) + 1];
    // Copy stored explicit attributes to the beginning of the array.
    System.arraycopy(state, 0, newState, 0, n);
    state = newState;
  }

  Object getAttributeValue(int index) {
    return attributeValues[index];
  }

  void setAttributeValue(Attribute attribute, Object value, boolean explicit) {
    String name = attribute.getName();
    Integer index = ruleClass.getAttributeIndex(name);
    if (!explicit && getExplicit(index)) {
      throw new IllegalArgumentException("attribute " + name + " already explicitly set");
    }
    attributeValues[index] = value;
    if (explicit) {
      setExplicit(index);
    }
  }
}
