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

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.auto.value.AutoValue;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.CompletionException;
import javax.annotation.Nullable;

/** Handles construction of {@link Fragment} from a {@link BuildOptions}. */
public final class FragmentFactory {

  /**
   * Creates the requested {@link Fragment} using a given {@link BuildOptions}.
   *
   * <p>Returns null if the fragment could not be built (e.g. the supplied BuildOptions does not
   * contain the required {@link FragmentOption}s).
   */
  @Nullable
  public Fragment createFragment(BuildOptions buildOptions, Class<? extends Fragment> fragmentClass)
      throws InvalidConfigurationException {
    BuildOptions trimmedOptions = trimToRequiredOptions(buildOptions, fragmentClass);
    Fragment fragment;
    FragmentKey fragmentKey = FragmentKey.create(trimmedOptions, fragmentClass);
    try {
      fragment = fragmentCache.get(fragmentKey);
    } catch (CompletionException e) {
      Throwables.propagateIfPossible(e.getCause(), InvalidConfigurationException.class);
      throw e;
    }
    if (fragment != NULL_MARKER) {
      return fragment;
    } else {
      // NULL_MARKER is never GC'ed, so this entry will stay in cache forever unless we delete it
      // ourselves. Since it's a cheap computation we don't care about recomputing it.
      fragmentCache.invalidate(fragmentKey);
      return null;
    }
  }

  /** Cache and associated infrastructure* */
  // Cache with weak values can't have null values.
  // TODO(blaze-configurability-team): At the moment, the only time shouldInclude is false is when
  //   TestFragment is constructed without TestOptions, which is already being registered as a
  //   required option of TestFragment. Should just abort fragment construction early when a
  //   required option is missing rather than use this NULL_MARKER infra.
  private static final Fragment NULL_MARKER = new Fragment() {};

  private final LoadingCache<FragmentKey, Fragment> fragmentCache =
      Caffeine.newBuilder().weakValues().build(FragmentFactory::makeFragment);

  private static BuildOptions trimToRequiredOptions(
      BuildOptions original, Class<? extends Fragment> fragment) {
    BuildOptions.Builder trimmed = BuildOptions.builder();
    ImmutableSet<Class<? extends FragmentOptions>> requiredOptions =
        Fragment.requiredOptions(fragment);
    for (FragmentOptions options : original.getNativeOptions()) {
      // CoreOptions is implicitly required by all fragments.
      if (options instanceof CoreOptions || requiredOptions.contains(options.getClass())) {
        trimmed.addFragmentOptions(options);
      }
    }
    if (Fragment.requiresStarlarkOptions(fragment)) {
      trimmed.addStarlarkOptions(original.getStarlarkOptions());
    }
    return trimmed.build();
  }

  @AutoValue
  abstract static class FragmentKey {
    // These BuildOptions should be already-trimmed to maximize cache efficacy
    abstract BuildOptions getBuildOptions();

    abstract Class<? extends Fragment> getFragmentClass();

    private static FragmentKey create(
        BuildOptions buildOptions, Class<? extends Fragment> fragmentClass) {
      return new AutoValue_FragmentFactory_FragmentKey(buildOptions, fragmentClass);
    }
  }

  private static Fragment makeFragment(FragmentKey fragmentKey)
      throws InvalidConfigurationException {
    BuildOptions buildOptions = fragmentKey.getBuildOptions();
    Class<? extends Fragment> fragmentClass = fragmentKey.getFragmentClass();
    String noConstructorPattern = "%s lacks constructor(BuildOptions)";
    try {
      Fragment fragment =
          fragmentClass.getConstructor(BuildOptions.class).newInstance(buildOptions);
      return fragment.shouldInclude() ? fragment : NULL_MARKER;
    } catch (InvocationTargetException e) {
      if (e.getCause() instanceof InvalidConfigurationException) {
        throw (InvalidConfigurationException) e.getCause();
      }
      throw new IllegalStateException(String.format(noConstructorPattern, fragmentClass), e);
    } catch (ReflectiveOperationException e) {
      throw new IllegalStateException(String.format(noConstructorPattern, fragmentClass), e);
    }
  }
}
