// 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_TEST_WITH_SCOPE_H_
#define TOOLS_GN_TEST_WITH_SCOPE_H_

#include <string>
#include <vector>

#include "base/macros.h"
#include "gn/build_settings.h"
#include "gn/c_tool.h"
#include "gn/err.h"
#include "gn/general_tool.h"
#include "gn/input_file.h"
#include "gn/parse_tree.h"
#include "gn/rust_tool.h"
#include "gn/scope.h"
#include "gn/scope_per_file_provider.h"
#include "gn/settings.h"
#include "gn/target.h"
#include "gn/token.h"
#include "gn/toolchain.h"
#include "gn/value.h"

// A helper class for setting up a Scope that a test can use. It makes a
// toolchain and sets up all the build state.
class TestWithScope {
 public:
  TestWithScope();
  ~TestWithScope();

  BuildSettings* build_settings() { return &build_settings_; }
  Settings* settings() { return &settings_; }
  const Settings* settings() const { return &settings_; }
  Toolchain* toolchain() { return &toolchain_; }
  const Toolchain* toolchain() const { return &toolchain_; }
  Scope* scope() { return &scope_; }
  const Scope::ItemVector& items() { return items_; }

  // This buffer accumulates output from any print() commands executed in the
  // context of this test. Note that the implementation of this is not
  // threadsafe so don't write tests that call print from multiple threads.
  std::string& print_output() { return print_output_; }

  // Parse the given string into a label in the default toolchain. This will
  // assert if the label isn't valid (this is intended for hardcoded labels).
  Label ParseLabel(const std::string& str) const;

  // Parses, evaluates, and resolves targets from the given snippet of code.
  // All targets must be defined in dependency order (does not use a Builder,
  // just blindly resolves all targets in order).
  bool ExecuteSnippet(const std::string& str, Err* err);

  Value ExecuteExpression(const std::string& expr, Err* err);

  // Fills in the tools for the given toolchain with reasonable default values.
  // The toolchain in this object will be automatically set up with this
  // function, it is exposed to allow tests to get the same functionality for
  // other toolchains they make.
  // Two slightly different toolchains can be generated by this function,
  // based on the use_toc argument. This is only currently required by
  // one test.
  static void SetupToolchain(Toolchain* toolchain, bool use_toc = false);

  // Sets the given text command on the given tool, parsing it as a
  // substitution pattern. This will assert if the input is malformed. This is
  // designed to help setting up Tools for tests.
  static void SetCommandForTool(const std::string& cmd, Tool* tool);

 private:
  void AppendPrintOutput(const std::string& str);

  BuildSettings build_settings_;
  Settings settings_;
  Toolchain toolchain_;
  Scope scope_;
  Scope::ItemVector items_;

  // Supplies the scope with built-in variables like root_out_dir.
  ScopePerFileProvider scope_progammatic_provider_;

  std::string print_output_;

  DISALLOW_COPY_AND_ASSIGN(TestWithScope);
};

// Helper class to treat some string input as a file.
//
// Instantiate it with the contents you want, be sure to check for error, and
// then you can execute the ParseNode or whatever.
class TestParseInput {
 public:
  explicit TestParseInput(const std::string& input);
  ~TestParseInput();

  // Indicates whether and what error occurred during tokenizing and parsing.
  bool has_error() const { return parse_err_.has_error(); }
  const Err& parse_err() const { return parse_err_; }

  const InputFile& input_file() const { return input_file_; }
  const std::vector<Token>& tokens() const { return tokens_; }
  const ParseNode* parsed() const { return parsed_.get(); }

 private:
  InputFile input_file_;

  std::vector<Token> tokens_;
  std::unique_ptr<ParseNode> parsed_;

  Err parse_err_;

  DISALLOW_COPY_AND_ASSIGN(TestParseInput);
};

// Shortcut for creating targets for tests that take the test setup, a pretty-
// style label, and a target type and sets everything up. The target will
// default to public visibility.
class TestTarget : public Target {
 public:
  TestTarget(const TestWithScope& setup,
             const std::string& label_string,
             Target::OutputType type);
  ~TestTarget() override;
};

#endif  // TOOLS_GN_TEST_WITH_SCOPE_H_
