// 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_SCHEDULER_H_
#define TOOLS_GN_SCHEDULER_H_

#include <map>

#include "base/atomic_ref_count.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "tools/gn/input_file_manager.h"
#include "tools/gn/label.h"
#include "tools/gn/source_file.h"
#include "tools/gn/token.h"

class Target;

// Maintains the thread pool and error state.
class Scheduler {
 public:
  Scheduler();
  ~Scheduler();

  bool Run();

  scoped_refptr<base::SingleThreadTaskRunner> task_runner() {
    return main_thread_task_runner_;
  }

  InputFileManager* input_file_manager() { return input_file_manager_.get(); }

  bool verbose_logging() const { return verbose_logging_; }
  void set_verbose_logging(bool v) { verbose_logging_ = v; }

  // TODO(brettw) data race on this access (benign?).
  bool is_failed() const { return is_failed_; }

  void Log(const std::string& verb, const std::string& msg);
  void FailWithError(const Err& err);

  void ScheduleWork(base::OnceClosure work);

  void Shutdown();

  // Declares that the given file was read and affected the build output.
  //
  // TODO(brettw) this is global rather than per-BuildSettings. If we
  // start using >1 build settings, then we probably want this to take a
  // BuildSettings object so we know the depdency on a per-build basis.
  // If moved, most of the Add/Get functions below should move as well.
  void AddGenDependency(const base::FilePath& file);
  std::vector<base::FilePath> GetGenDependencies() const;

  // Tracks calls to write_file for resolving with the unknown generated
  // inputs (see AddUnknownGeneratedInput below).
  void AddWrittenFile(const SourceFile& file);

  // Schedules a file to be written due to a target setting write_runtime_deps.
  void AddWriteRuntimeDepsTarget(const Target* entry);
  std::vector<const Target*> GetWriteRuntimeDepsTargets() const;
  bool IsFileGeneratedByWriteRuntimeDeps(const OutputFile& file) const;

  // Unknown generated inputs are files that a target declares as an input
  // in the output directory, but which aren't generated by any dependency.
  //
  // Some of these files will be files written by write_file and will be
  // GenDependencies (see AddWrittenFile above). There are OK and include
  // things like response files for scripts. Others cases will be ones where
  // the file is generated by a target that's not a dependency.
  //
  // In order to distinguish these two cases, the checking for these input
  // files needs to be done after all targets are complete. This also has the
  // nice side effect that if a target generates the file we can find it and
  // tell the user which dependency is missing.
  //
  // The result returned by GetUnknownGeneratedInputs will not count any files
  // that were written by write_file during execution.
  void AddUnknownGeneratedInput(const Target* target, const SourceFile& file);
  std::multimap<SourceFile, const Target*> GetUnknownGeneratedInputs() const;
  void ClearUnknownGeneratedInputsAndWrittenFiles();  // For testing.

  // We maintain a count of the things we need to do that works like a
  // refcount. When this reaches 0, the program exits.
  void IncrementWorkCount();
  void DecrementWorkCount();

  void SuppressOutputForTesting(bool suppress);

 private:
  void LogOnMainThread(const std::string& verb, const std::string& msg);
  void FailWithErrorOnMainThread(const Err& err);

  void DoTargetFileWrite(const Target* target);

  void DoWork(base::OnceClosure closure);

  void OnComplete();

  // Waits for tasks scheduled via ScheduleWork() to complete their execution.
  void WaitForPoolTasks();

  // TaskRunner for the thread on which the Scheduler is initialized.
  const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;

  scoped_refptr<InputFileManager> input_file_manager_;

  base::RunLoop runner_;

  bool verbose_logging_;

  base::AtomicRefCount work_count_;

  // Number of tasks scheduled by ScheduleWork() that haven't completed their
  // execution.
  base::AtomicRefCount pool_work_count_;

  // Lock for |pool_work_count_cv_|.
  base::Lock pool_work_count_lock_;

  // Condition variable signaled when |pool_work_count_| reaches zero.
  base::ConditionVariable pool_work_count_cv_;

  mutable base::Lock lock_;
  bool is_failed_;

  bool suppress_output_for_testing_;

  // Used to track whether the worker pool has been shutdown. This is necessary
  // to clean up after tests that make a scheduler but don't run the message
  // loop.
  bool has_been_shutdown_;

  // Protected by the lock. See the corresponding Add/Get functions above.
  std::vector<base::FilePath> gen_dependencies_;
  std::vector<SourceFile> written_files_;
  std::vector<const Target*> write_runtime_deps_targets_;
  std::multimap<SourceFile, const Target*> unknown_generated_inputs_;

  DISALLOW_COPY_AND_ASSIGN(Scheduler);
};

extern Scheduler* g_scheduler;

#endif  // TOOLS_GN_SCHEDULER_H_
