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

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.ActionLookupKey;
import com.google.devtools.build.lib.actions.BasicActionLookupValue;
import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoCollection;
import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoKey;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * Value that stores {@link BuildInfoCollection}s generated by {@link
 * com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory} instances. These collections
 * are used during analysis (see {@code CachingAnalysisEnvironment}).
 */
public class BuildInfoCollectionValue extends BasicActionLookupValue {
  private final BuildInfoCollection collection;

  BuildInfoCollectionValue(
      ImmutableList<ActionAnalysisMetadata> actions, BuildInfoCollection collection) {
    super(actions);
    this.collection = collection;
  }

  public BuildInfoCollection getCollection() {
    return collection;
  }

  @Override
  public String toString() {
    return getStringHelper().add("collection", collection).toString();
  }

  public static BuildInfoKeyAndConfig key(
      BuildInfoKey key, @Nullable BuildConfigurationValue config) {
    return BuildInfoKeyAndConfig.create(key, config == null ? null : config.getKey());
  }

  /** Key for BuildInfoCollectionValues. */
  @AutoCodec
  public static final class BuildInfoKeyAndConfig implements ActionLookupKey {
    private static final SkyKeyInterner<BuildInfoKeyAndConfig> keyInterner = SkyKey.newInterner();

    private final BuildInfoKey infoKey;
    private final BuildConfigurationKey configKey;

    private BuildInfoKeyAndConfig(BuildInfoKey key, BuildConfigurationKey configKey) {
      this.infoKey = Preconditions.checkNotNull(key, configKey);
      this.configKey = Preconditions.checkNotNull(configKey, key);
    }

    @AutoCodec.Instantiator
    static BuildInfoKeyAndConfig create(BuildInfoKey infoKey, BuildConfigurationKey configKey) {
      return keyInterner.intern(new BuildInfoKeyAndConfig(infoKey, configKey));
    }

    @Override
    public SkyFunctionName functionName() {
      return SkyFunctions.BUILD_INFO_COLLECTION;
    }

    @Override
    public BuildConfigurationKey getConfigurationKey() {
      return configKey;
    }

    BuildInfoKey getInfoKey() {
      return infoKey;
    }

    @Nullable
    @Override
    public Label getLabel() {
      return null;
    }

    @Override
    public int hashCode() {
      return Objects.hash(infoKey, configKey);
    }

    @Override
    public boolean equals(Object other) {
      if (this == other) {
        return true;
      }
      if (other == null) {
        return false;
      }
      if (this.getClass() != other.getClass()) {
        return false;
      }
      BuildInfoKeyAndConfig that = (BuildInfoKeyAndConfig) other;
      return Objects.equals(this.infoKey, that.infoKey)
          && Objects.equals(this.configKey, that.configKey);
    }

    @Override
    public SkyKeyInterner<BuildInfoKeyAndConfig> getSkyKeyInterner() {
      return keyInterner;
    }
  }
}
