// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_GN_SETUP_H_
#define TOOLS_GN_SETUP_H_

#include <memory>
#include <vector>

#include "base/files/file_path.h"
#include "base/macros.h"
#include "gn/build_settings.h"
#include "gn/builder.h"
#include "gn/label_pattern.h"
#include "gn/loader.h"
#include "gn/scheduler.h"
#include "gn/scope.h"
#include "gn/settings.h"
#include "gn/token.h"
#include "gn/toolchain.h"

class InputFile;
class ParseNode;

namespace base {
class CommandLine;
}

extern const char kDotfile_Help[];

// Helper class to set up the build settings and environment for the various
// commands to run.
class Setup {
 public:
  Setup();

  // Configures the build for the current command line. On success returns
  // true. On failure, prints the error and returns false.
  //
  // The parameter is the string the user specified for the build directory. We
  // will try to interpret this as a SourceDir if possible, and will fail if is
  // is malformed.
  //
  // With force_create = false, setup will fail if the build directory doesn't
  // already exist with an args file in it. With force_create set to true, the
  // directory will be created if necessary. Commands explicitly doing
  // generation should set this to true to create it, but querying commands
  // should set it to false to prevent creating oddly-named directories in case
  // the user omits the build directory argument (which is easy to do).
  //
  // cmdline is the gn invocation command, with flags like --root and --dotfile.
  // If no explicit cmdline is passed, base::CommandLine::ForCurrentProcess()
  // is used.
  bool DoSetup(const std::string& build_dir, bool force_create);
  bool DoSetup(const std::string& build_dir,
               bool force_create,
               const base::CommandLine& cmdline);

  // Runs the load, returning true on success. On failure, prints the error
  // and returns false. This includes both RunPreMessageLoop() and
  // RunPostMessageLoop().
  //
  // cmdline is the gn invocation command, with flags like --root and --dotfile.
  // If no explicit cmdline is passed, base::CommandLine::ForCurrentProcess()
  // is used.
  bool Run();
  bool Run(const base::CommandLine& cmdline);

  Scheduler& scheduler() { return scheduler_; }

  // Returns the file used to store the build arguments. Note that the path
  // might not exist.
  SourceFile GetBuildArgFile() const;

  // Sets whether the build arguments should be filled during setup from the
  // command line/build argument file. This will be true by default. The use
  // case for setting it to false is when editing build arguments, we don't
  // want to rely on them being valid.
  void set_fill_arguments(bool fa) { fill_arguments_ = fa; }

  // After a successful run, setting this will additionally cause the public
  // headers to be checked. Defaults to false.
  void set_check_public_headers(bool s) { check_public_headers_ = s; }

  // After a successful run, setting this will additionally cause system style
  // includes to be checked. Defaults to false.
  void set_check_system_includes(bool s) { check_system_includes_ = s; }

  bool check_system_includes() const { return check_system_includes_; }

  // Before DoSetup, setting this will generate an empty args.gn if
  // it does not exist and set up correct dependencies for it.
  void set_gen_empty_args(bool ge) { gen_empty_args_ = ge; }

  // Read from the .gn file, these are the targets to check. If the .gn file
  // does not specify anything, this will be null. If the .gn file specifies
  // the empty list, this will be non-null but empty.
  const std::vector<LabelPattern>* check_patterns() const {
    return check_patterns_.get();
  }

  BuildSettings& build_settings() { return build_settings_; }
  Builder& builder() { return builder_; }
  LoaderImpl* loader() { return loader_.get(); }

  const SourceFile& GetDotFile() const { return dotfile_input_file_->name(); }

  // Name of the file in the root build directory that contains the build
  // arguments.
  static const char kBuildArgFileName[];

 private:
  // Performs the two sets of operations to run the generation before and after
  // the message loop is run.
  void RunPreMessageLoop();
  bool RunPostMessageLoop(const base::CommandLine& cmdline);

  // Fills build arguments. Returns true on success.
  bool FillArguments(const base::CommandLine& cmdline);

  // Fills the build arguments from the command line or from the build arg file.
  bool FillArgsFromCommandLine(const std::string& args);
  bool FillArgsFromFile();

  // Given an already-loaded args_input_file_, parses and saves the resulting
  // arguments. Backend for the different FillArgs variants.
  bool FillArgsFromArgsInputFile();

  // Writes the build arguments to the build arg file.
  bool SaveArgsToFile();

  // Fills the root directory into the settings. Returns true on success.
  bool FillSourceDir(const base::CommandLine& cmdline);

  // Fills the build directory given the value the user has specified.
  // Must happen after FillSourceDir so we can resolve source-relative
  // paths. If require_exists is false, it will fail if the dir doesn't exist.
  bool FillBuildDir(const std::string& build_dir, bool require_exists);

  // Fills the python path portion of the command line. On failure, sets
  // it to just "python".
  bool FillPythonPath(const base::CommandLine& cmdline);

  // Run config file.
  bool RunConfigFile();

  bool FillOtherConfig(const base::CommandLine& cmdline);

  BuildSettings build_settings_;
  scoped_refptr<LoaderImpl> loader_;
  Builder builder_;

  SourceFile root_build_file_;

  bool check_public_headers_ = false;
  bool check_system_includes_ = false;

  // See getter for info.
  std::unique_ptr<std::vector<LabelPattern>> check_patterns_;

  Scheduler scheduler_;

  // These settings and toolchain are used to interpret the command line and
  // dot file.
  Settings dotfile_settings_;
  Scope dotfile_scope_;

  // State for invoking the dotfile.
  base::FilePath dotfile_name_;
  std::unique_ptr<InputFile> dotfile_input_file_;
  std::vector<Token> dotfile_tokens_;
  std::unique_ptr<ParseNode> dotfile_root_;

  // Default overrides, specified in the dotfile.
  // Owned by the Value (if it exists) in the dotfile_scope_.
  const Scope* default_args_ = nullptr;

  // Set to true when we should populate the build arguments from the command
  // line or build argument file. See setter above.
  bool fill_arguments_ = true;

  // Generate an empty args.gn file if it does not exists.
  bool gen_empty_args_ = false;

  // State for invoking the command line args. We specifically want to keep
  // this around for the entire run so that Values can blame to the command
  // line when we issue errors about them.
  std::unique_ptr<InputFile> args_input_file_;
  std::vector<Token> args_tokens_;
  std::unique_ptr<ParseNode> args_root_;

  DISALLOW_COPY_AND_ASSIGN(Setup);
};

#endif  // TOOLS_GN_SETUP_H_
