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

import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.util.GroupedList;
import com.google.devtools.build.lib.util.GroupedList.GroupedListHelper;
import java.math.BigInteger;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

/** Convenience class for {@link NodeEntry} implementations that delegate many operations. */
public abstract class DelegatingNodeEntry implements NodeEntry {
  protected abstract NodeEntry getDelegate();

  protected ThinNodeEntry getThinDelegate() {
    return getDelegate();
  }

  @Override
  public SkyValue getValue() throws InterruptedException {
    return getDelegate().getValue();
  }

  @Override
  public SkyValue getValueMaybeWithMetadata() throws InterruptedException {
    return getDelegate().getValueMaybeWithMetadata();
  }

  @Override
  public SkyValue toValue() throws InterruptedException {
    return getDelegate().toValue();
  }

  @Nullable
  @Override
  public ErrorInfo getErrorInfo() throws InterruptedException {
    return getDelegate().getErrorInfo();
  }

  @Override
  public Set<SkyKey> getInProgressReverseDeps() {
    return getDelegate().getInProgressReverseDeps();
  }

  @Override
  public Set<SkyKey> setValue(
      SkyValue value, Version version, DepFingerprintList depFingerprintList)
      throws InterruptedException {
    return getDelegate().setValue(value, version, depFingerprintList);
  }

  @Override
  public DependencyState addReverseDepAndCheckIfDone(@Nullable SkyKey reverseDep)
      throws InterruptedException {
    return getDelegate().addReverseDepAndCheckIfDone(reverseDep);
  }

  @Override
  public DependencyState checkIfDoneForDirtyReverseDep(SkyKey reverseDep)
      throws InterruptedException {
    return getDelegate().checkIfDoneForDirtyReverseDep(reverseDep);
  }

  @Override
  public boolean signalDep(Version childVersion, @Nullable SkyKey childForDebugging) {
    return getDelegate().signalDep(childVersion, childForDebugging);
  }

  @Override
  public Set<SkyKey> markClean() throws InterruptedException {
    return getDelegate().markClean();
  }

  @Override
  public void forceRebuild() {
    getDelegate().forceRebuild();
  }

  @Override
  public Version getVersion() {
    return getDelegate().getVersion();
  }

  @Override
  public DirtyState getDirtyState() {
    return getDelegate().getDirtyState();
  }

  @Override
  public List<SkyKey> getNextDirtyDirectDeps() throws InterruptedException {
    return getDelegate().getNextDirtyDirectDeps();
  }

  @Override
  public Iterable<SkyKey> getAllDirectDepsForIncompleteNode() throws InterruptedException {
    return getDelegate().getAllDirectDepsForIncompleteNode();
  }

  @Override
  public ImmutableSet<SkyKey> getAllRemainingDirtyDirectDeps() throws InterruptedException {
    return getDelegate().getAllRemainingDirtyDirectDeps();
  }

  @Override
  public boolean canPruneDepsByFingerprint() {
    return getDelegate().canPruneDepsByFingerprint();
  }

  @Nullable
  @Override
  public Iterable<SkyKey> getLastDirectDepsGroupWhenPruningDepsByFingerprint()
      throws InterruptedException {
    return getDelegate().getLastDirectDepsGroupWhenPruningDepsByFingerprint();
  }

  @Override
  public boolean unmarkNeedsRebuildingIfGroupUnchangedUsingFingerprint(
      BigInteger groupFingerprint) {
    return getDelegate().unmarkNeedsRebuildingIfGroupUnchangedUsingFingerprint(groupFingerprint);
  }

  @Override
  public Iterable<SkyKey> getAllReverseDepsForNodeBeingDeleted() {
    return getDelegate().getAllReverseDepsForNodeBeingDeleted();
  }

  @Override
  public void markRebuilding() {
    getDelegate().markRebuilding();
  }

  @Override
  public GroupedList<SkyKey> getTemporaryDirectDeps() {
    return getDelegate().getTemporaryDirectDeps();
  }

  @Override
  public boolean noDepsLastBuild() {
    return getDelegate().noDepsLastBuild();
  }

  @Override
  public void removeUnfinishedDeps(Set<SkyKey> unfinishedDeps) {
    getDelegate().removeUnfinishedDeps(unfinishedDeps);
  }

  @Override
  public void resetForRestartFromScratch() {
    getDelegate().resetForRestartFromScratch();
  }

  @Override
  public Set<SkyKey> addTemporaryDirectDeps(GroupedListHelper<SkyKey> helper) {
    return getDelegate().addTemporaryDirectDeps(helper);
  }

  @Override
  public boolean isReady() {
    return getDelegate().isReady();
  }

  @Override
  public boolean isDone() {
    return getThinDelegate().isDone();
  }

  @Override
  public Iterable<SkyKey> getDirectDeps() throws InterruptedException {
    return getDelegate().getDirectDeps();
  }

  @Override
  public void removeReverseDep(SkyKey reverseDep) throws InterruptedException {
    getDelegate().removeReverseDep(reverseDep);
  }

  @Override
  public void removeInProgressReverseDep(SkyKey reverseDep) {
    getDelegate().removeInProgressReverseDep(reverseDep);
  }

  @Override
  public Iterable<SkyKey> getReverseDepsForDoneEntry() throws InterruptedException {
    return getDelegate().getReverseDepsForDoneEntry();
  }

  @Override
  public boolean isDirty() {
    return getThinDelegate().isDirty();
  }

  @Override
  public boolean isChanged() {
    return getThinDelegate().isChanged();
  }

  @Override
  @Nullable
  public MarkedDirtyResult markDirty(DirtyType dirtyType) throws InterruptedException {
    return getThinDelegate().markDirty(dirtyType);
  }

  @Override
  public void addTemporaryDirectDepsGroupToDirtyEntry(List<SkyKey> group) {
    getDelegate().addTemporaryDirectDepsGroupToDirtyEntry(group);
  }

  @Override
  public void addExternalDep() {
    getDelegate().addExternalDep();
  }
}
