// Copyright 2018 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.skyframe;

import com.google.common.base.Preconditions;
import com.google.common.collect.Iterators;
import java.math.BigInteger;
import java.util.Iterator;
import javax.annotation.Nullable;

/** List of fingerprints, each of which is a nullable {@link BigInteger}. Ordered and immutable. */
public class DepFingerprintList implements Iterable<BigInteger> {
  /**
   * Marker object indicating that dep fingerprints are not being tracked, and so there should be no
   * attempts to use this dep fingerprints object. Clients can compare their {@code
   * DepFingerprintList} object to this one using reference equality to see if they are tracking dep
   * fingerprints. This object should never be passed in as a valid {@code DepFingerprintList}
   * object.
   */
  public static final DepFingerprintList NOT_TRACKING_MARKER = new NoDepGroupsFingerprintMarker();

  private static final DepFingerprintList EMPTY_DEP_GROUPS_FINGERPRINT =
      new DepFingerprintList(new BigInteger[0]);

  private final BigInteger[] fingerprints;

  private DepFingerprintList(BigInteger[] fingerprints) {
    this.fingerprints = fingerprints;
  }

  /**
   * Returns the {@link BigInteger} for the dep group at {@code index}. A null value indicates that
   * a fingerprint could not be computed for this group, so that equality-by-dep-group checking
   * cannot be performed for this group.
   */
  @Nullable
  public BigInteger get(int index) {
    return fingerprints[index];
  }

  @Override
  public Iterator<BigInteger> iterator() {
    return Iterators.forArray(fingerprints);
  }

  private static class NoDepGroupsFingerprintMarker extends DepFingerprintList {
    private NoDepGroupsFingerprintMarker() {
      super(null);
    }

    @Override
    public BigInteger get(int index) {
      throw new UnsupportedOperationException("No dep groups fingerprint (" + index + ")");
    }

    @Override
    public Iterator<BigInteger> iterator() {
      throw new UnsupportedOperationException("No dep groups fingerprint");
    }
  }

  /** Builder for {@code DepFingerprintList}. */
  public static class Builder {
    private int curIndex = 0;
    private final BigInteger[] fingerprints;

    public Builder(int size) {
      fingerprints = new BigInteger[size];
    }

    public void add(BigInteger fingerprint) {
      fingerprints[curIndex++] = fingerprint;
    }

    public DepFingerprintList build() {
      Preconditions.checkState(
          curIndex == fingerprints.length, "%s %s", curIndex, fingerprints.length);
      if (fingerprints.length == 0) {
        return EMPTY_DEP_GROUPS_FINGERPRINT;
      }
      return new DepFingerprintList(fingerprints);
    }
  }
}
