// Copyright 2021 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.bazel.bzlmod;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Interner;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.skyframe.SkyFunctions;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.skyframe.AbstractSkyKey;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyValue;

/** The result of evaluating a single module extension (see {@link SingleExtensionEvalFunction}). */
@AutoCodec(explicitlyAllowClass = {Package.class})
@AutoValue
public abstract class SingleExtensionEvalValue implements SkyValue {
  /**
   * Returns the repos generated by the extension. The key is the "internal name" (as specified by
   * the extension) of the repo, and the value is the the repo specs that defins the repository .
   */
  public abstract ImmutableMap<String, RepoSpec> getGeneratedRepoSpecs();

  /**
   * Returns the mapping from the canonical repo names of the repos generated by this extension to
   * their "internal name" (as specified by the extension).
   */
  public abstract ImmutableBiMap<RepositoryName, String> getCanonicalRepoNameToInternalNames();

  @AutoCodec.Instantiator
  public static SingleExtensionEvalValue create(
      ImmutableMap<String, RepoSpec> generatedRepoSpecs,
      ImmutableBiMap<RepositoryName, String> canonicalRepoNameToInternalNames) {
    return new AutoValue_SingleExtensionEvalValue(
        generatedRepoSpecs, canonicalRepoNameToInternalNames);
  }

  public static Key key(ModuleExtensionId id) {
    return Key.create(id);
  }

  /**
   * The {@link com.google.devtools.build.skyframe.SkyKey} of a {@link
   * com.google.devtools.build.lib.bazel.bzlmod.SingleExtensionEvalValue}
   */
  @AutoCodec
  public static class Key extends AbstractSkyKey<ModuleExtensionId> {
    private static final Interner<Key> interner = BlazeInterners.newWeakInterner();

    protected Key(ModuleExtensionId arg) {
      super(arg);
    }

    @AutoCodec.Instantiator
    static Key create(ModuleExtensionId arg) {
      return interner.intern(new Key(arg));
    }

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