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

import com.google.common.collect.ImmutableMap;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * Possible test sizes.
 *
 * Test size may affect the way how test is executed - e.g., it will determine
 * default timeout value and estimated local resource usage.
 */
public enum TestSize {

  // Small tests use small amount of memory, but CPU intensive.
  SMALL(TestTimeout.SHORT, 2),
  // Medium tests tend to use larger amount of memory.
  MEDIUM(TestTimeout.MODERATE, 10),
  // All other tests estimated to use fairly large amount of memory.
  LARGE(TestTimeout.LONG, 20),
  ENORMOUS(TestTimeout.ETERNAL, 30);

  // Memoize canonical lowercase name -> TestSize mappings to avoid extraneous toUpperCases for
  // valueOf.
  private static final ImmutableMap<String, TestSize> CANONICAL_LOWER_CASE_NAME_TABLE;
  static {
    ImmutableMap.Builder<String, TestSize> builder = ImmutableMap.builder();
    for (TestSize size : TestSize.values()) {
      builder.put(size.name().toLowerCase(), size);
    }
    CANONICAL_LOWER_CASE_NAME_TABLE = builder.buildOrThrow();
  }

  private final TestTimeout timeout;
  private final int defaultShards;

  TestSize(TestTimeout defaultTimeout, int defaultShards) {
    this.timeout = defaultTimeout;
    this.defaultShards = defaultShards;
  }

  /**
   * Returns default timeout in seconds.
   */
  public TestTimeout getDefaultTimeout() {
    return timeout;
  }

  /**
   * Returns default number of shards.
   */
  public int getDefaultShards() { return defaultShards; }

  /** Returns test size of the given test target, or null if the size attribute is unrecognized. */
  public static TestSize getTestSize(Rule testTarget) {
    String attr = NonconfigurableAttributeMapper.of(testTarget).get("size", Type.STRING);
    return getTestSize(attr);
  }

  /**
   * Returns {@link TestSize} matching the given timeout or null if the given timeout doesn't match
   * any {@link TestSize}.
   *
   * @param timeout The timeout associated with the desired TestSize.
   */
  @Nullable
  public static TestSize getTestSize(TestTimeout timeout) {
    for (TestSize size : TestSize.values()) {
      if (size.timeout == timeout) {
        return size;
      }
    }
    return null;
  }

  /**
   * Returns the enum associated with a test's size or null if the tag is not lower case or an
   * unknown size.
   */
  @Nullable
  public static TestSize getTestSize(String attr) {
    if (!attr.equals(attr.toLowerCase())) {
      return null;
    }
    try {
      return CANONICAL_LOWER_CASE_NAME_TABLE.get(attr);
    } catch (IllegalArgumentException e) {
      return null;
    }
  }

  /** Normal practice is to always use size tags as lower case strings. */
  @Override
  public String toString() {
    return super.toString().toLowerCase();
  }

  /**
   * Converter for the --test_size_filters option.
   */
  public static class TestSizeFilterConverter extends EnumFilterConverter<TestSize> {
    public TestSizeFilterConverter() {
      super(TestSize.class, "test size");
    }

    /**
     * {@inheritDoc}
     *
     * <p>This override is necessary to prevent OptionsData from throwing a "must be assignable from
     * the converter return type" exception. OptionsData doesn't recognize the generic type and
     * actual type are the same.
     */
    @Override
    public final Set<TestSize> convert(String input) throws OptionsParsingException {
      return super.convert(input);
    }
  }
}
