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

import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.pkgcache.PackageOptions;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.runtime.events.GotProjectFileEvent;
import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.common.options.OptionPriority.PriorityCategory;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.OptionsParsingResult;
import java.util.List;

/**
 * Provides support for implementations for {@link
 * com.google.devtools.build.lib.runtime.BlazeCommand} to work with {@link ProjectFile}.
 */
public final class ProjectFileSupport {
  static final String PROJECT_FILE_PREFIX = "+";

  private ProjectFileSupport() {}

  /**
   * Reads any project files specified on the command line and updates the options parser
   * accordingly. If project files cannot be read or if they contain unparsable options, or if they
   * are not enabled, then it throws an exception instead.
   */
  public static void handleProjectFiles(
      ExtendedEventHandler eventHandler,
      ProjectFile.Provider projectFileProvider,
      Path workspaceDir,
      Path workingDir,
      OptionsParser optionsParser,
      String command)
      throws OptionsParsingException, InterruptedException, AbruptExitException {
    List<String> targets = optionsParser.getResidue();
    if (projectFileProvider != null
        && !targets.isEmpty()
        && targets.get(0).startsWith(PROJECT_FILE_PREFIX)) {
      if (targets.size() > 1) {
        throw new OptionsParsingException("Cannot handle more than one +<file> argument yet");
      }
      if (!optionsParser.getOptions(CommonCommandOptions.class).allowProjectFiles) {
        throw new OptionsParsingException(
            "project file support is not enabled. "
                + "Pass --experimental_allow_project_files to enable.");
      }
      // TODO(bazel-team): This is currently treated as a path relative to the workspace - if the
      // cwd is a subdirectory of the workspace, that will be surprising, and we should interpret it
      // relative to the cwd instead.
      PathFragment projectFilePath = PathFragment.create(targets.get(0).substring(1));
      List<Root> packagePath =
          PathPackageLocator.create(
                  // We only need a non-null outputBase for the PathPackageLocator if we support
                  // external
                  // repositories, which we don't for project files.
                  null,
                  optionsParser.getOptions(PackageOptions.class).packagePath,
                  eventHandler,
                  workspaceDir,
                  workingDir,
                  BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY)
              .getPathEntries();
      ProjectFile projectFile =
          projectFileProvider.getProjectFile(
              workingDir, packagePath, projectFilePath, optionsParser);
      eventHandler.handle(Event.info("Using " + projectFile.getName()));

      optionsParser.parse(
          PriorityCategory.RC_FILE,
          projectFile.getName(),
          projectFile.getCommandLineFor(command, eventHandler));
      eventHandler.post(new GotProjectFileEvent(projectFile.getName()));
    }
  }

  /**
   * Returns a list of targets from the options residue. If a project file is supplied as the first
   * argument, it will be ignored, on the assumption that handleProjectFiles() has been called to
   * process it.
   */
  public static List<String> getTargets(
      ProjectFile.Provider projectFileProvider, OptionsParsingResult options) {
    List<String> targets = options.getResidue();
    if (projectFileProvider != null
        && !targets.isEmpty()
        && targets.get(0).startsWith(PROJECT_FILE_PREFIX)) {
      return targets.subList(1, targets.size());
    }
    return targets;
  }
}
