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

import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.runtime.BlazeCommand;
import com.google.devtools.build.lib.runtime.CommonCommandOptions;
import com.google.devtools.build.lib.runtime.ProjectFile;
import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants;
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 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 {
    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(PackageCacheOptions.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.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;
  }
}
