// Copyright 2020 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.analysis;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.skylarkbuildapi.platform.ExecGroupCollectionApi;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Identifier;
import com.google.devtools.build.lib.syntax.Printer;
import com.google.devtools.build.lib.syntax.Starlark;
import com.google.devtools.build.lib.syntax.StarlarkIndexable;
import com.google.devtools.build.lib.syntax.StarlarkSemantics;
import java.util.List;
import java.util.stream.Collectors;

/**
 * A {@link StarlarkIndexable} collection of resolved toolchain contexts that can be exposed to
 * starlark.
 */
public class ExecGroupCollection extends ToolchainCollection<ResolvedToolchainContext>
    implements ExecGroupCollectionApi {

  public ExecGroupCollection(ToolchainCollection<ResolvedToolchainContext> toolchainCollection) {
    super(toolchainCollection);
  }

  @VisibleForTesting
  public ImmutableMap<String, ResolvedToolchainContext> getToolchainCollectionForTesting() {
    return getContextMap();
  }

  public static boolean isValidGroupName(String execGroupName) {
    return !execGroupName.equals(DEFAULT_EXEC_GROUP_NAME) && Identifier.isValid(execGroupName);
  }

  @Override
  public boolean containsKey(StarlarkSemantics semantics, Object key) throws EvalException {
    String group = castGroupName(key);
    return !DEFAULT_EXEC_GROUP_NAME.equals(group) && getExecGroups().contains(group);
  }

  /**
   * This creates a new {@link ExecGroupContext} object every time this is called. This seems better
   * than pre-creating and storing all {@link ExecGroupContext}s since they're just thin wrappers
   * around {@link ResolvedToolchainContext} objects.
   */
  @Override
  public ExecGroupContext getIndex(StarlarkSemantics semantics, Object key) throws EvalException {
    String execGroup = castGroupName(key);
    if (!containsKey(semantics, key)) {
      throw Starlark.errorf(
          "In %s, unrecognized exec group '%s' requested. Available exec groups: [%s]",
          getDefaultToolchainContext().targetDescription(),
          execGroup,
          String.join(", ", getScrubbedExecGroups()));
    }
    return new ExecGroupContext(getToolchainContext(execGroup));
  }

  private static String castGroupName(Object key) throws EvalException {
    if (!(key instanceof String)) {
      throw Starlark.errorf(
          "exec groups only support indexing by exec group name, got %s of type %s instead",
          Starlark.repr(key), Starlark.type(key));
    }
    return (String) key;
  }

  @Override
  public void repr(Printer printer) {
    printer
        .append("<ctx.exec_groups: ")
        .append(String.join(", ", getScrubbedExecGroups()))
        .append(">");
  }

  private List<String> getScrubbedExecGroups() {
    return getExecGroups().stream()
        .filter(group -> !DEFAULT_EXEC_GROUP_NAME.equals(group))
        .sorted()
        .collect(Collectors.toList());
  }

  /**
   * The starlark object that is returned by ctx.exec_groups[<name>]. Gives information about that
   * exec group.
   */
  public static class ExecGroupContext implements ExecGroupContextApi {
    ResolvedToolchainContext resolvedToolchainContext;

    private ExecGroupContext(ResolvedToolchainContext resolvedToolchainContext) {
      this.resolvedToolchainContext = resolvedToolchainContext;
    }

    @Override
    public ResolvedToolchainContext toolchains() throws EvalException {
      return resolvedToolchainContext;
    }

    @Override
    public void repr(Printer printer) {
      printer.append("<exec_group_context>");
    }
  }
}
