// 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_LOADER_H_
#define TOOLS_GN_LOADER_H_

#include <map>
#include <set>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "tools/gn/label.h"
#include "tools/gn/scope.h"

namespace base {
class MessageLoop;
}

class BuildSettings;
class LocationRange;
class Settings;
class SourceFile;
class Toolchain;

// The loader manages execution of the different build files. It receives
// requests (normally from the Builder) when new references are found, and also
// manages loading the build config files.
//
// This loader class is abstract so it can be mocked out for testing the
// Builder.
class Loader : public base::RefCountedThreadSafe<Loader> {
 public:
  Loader();

  // Loads the given file in the conext of the given toolchain. The initial
  // call to this (the one that actually starts the generation) should have an
  // empty toolchain name, which will trigger the load of the default build
  // config.
  virtual void Load(const SourceFile& file,
                    const LocationRange& origin,
                    const Label& toolchain_name) = 0;

  // Notification that the given toolchain has loaded. This will unblock files
  // waiting on this definition.
  virtual void ToolchainLoaded(const Toolchain* toolchain) = 0;

  // Returns the label of the default toolchain.
  virtual Label GetDefaultToolchain() const = 0;

  // Returns information about the toolchain with the given label. Will return
  // false if we haven't processed this toolchain yet.
  virtual const Settings* GetToolchainSettings(const Label& label) const = 0;

  // Helper function that extracts the file and toolchain name from the given
  // label, and calls Load().
  void Load(const Label& label, const LocationRange& origin);

  // Returns the build file that the given label references.
  static SourceFile BuildFileForLabel(const Label& label);

  // When processing the default build config, we want to capture the argument
  // of set_default_build_config. The implementation of that function uses this
  // constant as a property key to get the Label* out of the scope where the
  // label should be stored.
  static const void* kDefaultToolchainKey;

 protected:
  friend class base::RefCountedThreadSafe<Loader>;
  virtual ~Loader();
};

class LoaderImpl : public Loader {
 public:
  // Callback to emulate InputFileManager::AsyncLoadFile.
  typedef base::Callback<bool(const LocationRange&,
                              const BuildSettings*,
                              const SourceFile&,
                              const base::Callback<void(const ParseNode*)>&,
                              Err*)> AsyncLoadFileCallback;

  LoaderImpl(const BuildSettings* build_settings);

  // Loader implementation.
  virtual void Load(const SourceFile& file,
                    const LocationRange& origin,
                    const Label& toolchain_name) OVERRIDE;
  virtual void ToolchainLoaded(const Toolchain* toolchain) OVERRIDE;
  virtual Label GetDefaultToolchain() const OVERRIDE;
  virtual const Settings* GetToolchainSettings(
      const Label& label) const OVERRIDE;

  // Sets the message loop corresponding to the main thread. By default this
  // class will use the thread active during construction, but there is not
  // a message loop active during construction all the time.
  void set_main_loop(base::MessageLoop* loop) { main_loop_ = loop; }

  // The complete callback is called whenever there are no more pending loads.
  // Called on the main thread only. This may be called more than once if the
  // queue is drained, but then more stuff gets added.
  void set_complete_callback(const base::Closure& cb) {
    complete_callback_ = cb;
  }

  // This callback is used when the loader finds it wants to load a file.
  void set_async_load_file(const AsyncLoadFileCallback& cb) {
    async_load_file_ = cb;
  }

  const Label& default_toolchain_label() const {
    return default_toolchain_label_;
  }

 private:
  struct LoadID;
  struct ToolchainRecord;

  virtual ~LoaderImpl();

  // Schedules the input file manager to load the given file.
  void ScheduleLoadFile(const Settings* settings,
                        const LocationRange& origin,
                        const SourceFile& file);
  void ScheduleLoadBuildConfig(
      Settings* settings,
      const Scope::KeyValueMap& toolchain_overrides);

  // Runs the given file on the background thread. These are called by the
  // input file manager.
  void BackgroundLoadFile(const Settings* settings,
                          const SourceFile& file_name,
                          const ParseNode* root);
  void BackgroundLoadBuildConfig(
      Settings* settings,
      const Scope::KeyValueMap& toolchain_overrides,
      const ParseNode* root);

  // Posted to the main thread when any file other than a build config file
  // file has completed running.
  void DidLoadFile();

  // Posted to the main thread when any build config file has completed
  // running. The label should be the name of the toolchain.
  //
  // If there is no defauled toolchain loaded yet, we'll assume that the first
  // call to this indicates to the default toolchain, and this function will
  // set the default toolchain name to the given label.
  void DidLoadBuildConfig(const Label& label);

  // Decrements the pending_loads_ variable and issues the complete callback if
  // necessary.
  void DecrementPendingLoads();

  // Forwards to the appropriate location to load the file.
  bool AsyncLoadFile(const LocationRange& origin,
                     const BuildSettings* build_settings,
                     const SourceFile& file_name,
                     const base::Callback<void(const ParseNode*)>& callback,
                     Err* err);

  base::MessageLoop* main_loop_;

  int pending_loads_;
  base::Closure complete_callback_;

  // When non-null, use this callback instead of the InputFileManager for
  // mocking purposes.
  AsyncLoadFileCallback async_load_file_;

  typedef std::set<LoadID> LoadIDSet;
  LoadIDSet invocations_;

  const BuildSettings* build_settings_;
  Label default_toolchain_label_;

  // Records for the build config file loads.
  // Owning pointers.
  typedef std::map<Label, ToolchainRecord*> ToolchainRecordMap;
  ToolchainRecordMap toolchain_records_;
};

#endif  // TOOLS_GN_LOADER_H_
