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

import com.google.common.cache.Cache;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.ConfigurationCollectionFactory;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.util.Preconditions;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * A factory class for {@link BuildConfiguration} instances. This is unfortunately more complex,
 * and should be simplified in the future, if
 * possible. Right now, creating a {@link BuildConfiguration} instance involves
 * creating the instance itself and the related configurations; the main method
 * is {@link #createConfigurations}.
 *
 * <p>Avoid calling into this class, and instead use the skyframe infrastructure to obtain
 * configuration instances.
 *
 * <p>Blaze currently relies on the fact that all {@link BuildConfiguration}
 * instances used in a build can be constructed ahead of time by this class.
 */
@ThreadCompatible // safe as long as separate instances are used
public final class ConfigurationFactory {
  private final List<ConfigurationFragmentFactory> configurationFragmentFactories;
  private final ConfigurationCollectionFactory configurationCollectionFactory;

  public ConfigurationFactory(
      ConfigurationCollectionFactory configurationCollectionFactory,
      ConfigurationFragmentFactory... fragmentFactories) {
    this(configurationCollectionFactory, ImmutableList.copyOf(fragmentFactories));
  }

  public ConfigurationFactory(
      ConfigurationCollectionFactory configurationCollectionFactory,
      List<ConfigurationFragmentFactory> fragmentFactories) {
    this.configurationCollectionFactory =
        Preconditions.checkNotNull(configurationCollectionFactory);
    this.configurationFragmentFactories = ImmutableList.copyOf(fragmentFactories);
  }

  /**
   * Creates a set of build configurations with top-level configuration having the given options.
   *
   * <p>The rest of the configurations are created based on the set of transitions available.
   */
  @Nullable
  public BuildConfiguration createConfigurations(
      Cache<String, BuildConfiguration> cache,
      PackageProviderForConfigurations loadedPackageProvider,
      BuildOptions buildOptions,
      EventHandler errorEventListener)
      throws InvalidConfigurationException, InterruptedException {
    return configurationCollectionFactory.createConfigurations(this, cache,
        loadedPackageProvider, buildOptions, errorEventListener);
  }

  /**
   * Returns a {@link com.google.devtools.build.lib.analysis.config.BuildConfiguration} based on the
   * given set of build options.
   *
   * <p>If the configuration has already been created, re-uses it, otherwise, creates a new one.
   */
  @Nullable
  public BuildConfiguration getConfiguration(
      PackageProviderForConfigurations loadedPackageProvider,
      BuildOptions buildOptions,
      boolean actionsDisabled,
      Cache<String, BuildConfiguration> cache)
      throws InvalidConfigurationException, InterruptedException {

    String cacheKey = buildOptions.computeCacheKey();
    BuildConfiguration result = cache.getIfPresent(cacheKey);
    if (result != null) {
      return result;
    }

    Map<Class<? extends Fragment>, Fragment> fragments = new HashMap<>();
    // Create configuration fragments
    for (ConfigurationFragmentFactory factory : configurationFragmentFactories) {
      Class<? extends Fragment> fragmentType = factory.creates();
      Fragment fragment = loadedPackageProvider.getFragment(buildOptions, fragmentType);
      if (fragment != null && fragments.get(fragment.getClass()) == null) {
        fragments.put(fragment.getClass(), fragment);
      }
    }
    BlazeDirectories directories = loadedPackageProvider.getDirectories();
    if (loadedPackageProvider.valuesMissing()) {
      return null;
    }

    result = new BuildConfiguration(directories, fragments, buildOptions, actionsDisabled);
    cache.put(cacheKey, result);
    return result;
  }

  public List<ConfigurationFragmentFactory> getFactories() {
    return configurationFragmentFactories;
  }
}
