// Copyright 2021 The Chromium OS 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 MISSIVE_UTIL_TASK_RUNNER_CONTEXT_H_
#define MISSIVE_UTIL_TASK_RUNNER_CONTEXT_H_

#include <utility>

#include <base/bind.h>
#include <base/callback.h>
#include <base/callback_helpers.h>
#include <base/check.h>
#include <base/logging.h>
#include <base/memory/scoped_refptr.h>
#include <base/sequence_checker.h>
#include <base/sequenced_task_runner.h>
#include <base/time/time.h>

namespace reporting {

// This class defines context for multiple actions executed on a sequenced task
// runner with the ability to make asynchronous calls to other threads and
// resuming sequenced execution by calling |Schedule| or |ScheduleAfter|.
// Multiple actions can be scheduled at once; they will be executed on the same
// sequenced task runner. Ends execution and self-destructs when one of the
// actions calls |Response| (all previously scheduled actions must be completed
// or cancelled by then, otherwise they will crash).
//
// Code snippet:
//
// Declaration:
// class SeriesOfActionsContext {
//    public:
//     SeriesOfActionsContext(
//         ...,
//         base::OnceCallback<void(...)> callback,
//         scoped_refptr<base::SequencedTaskRunner> task_runner)
//         : TaskRunnerContext<...>(std::move(callback),
//                                  std::move(task_runner)) {}
//
//    private:
//     // Context can only be deleted by calling Response method.
//     ~SeriesOfActionsContext() override = default;
//
//     void Action1(...) {
//       ...
//       if (...) {
//         Response(...);
//         return;
//       }
//       Schedule(&SeriesOfActionsContext::Action2,
//                base::Unretained(this),
//                ...);
//       ...
//       ScheduleAfter(delay,
//                     &SeriesOfActionsContext::Action3,
//                     base::Unretained(this),
//                     ...);
//     }
//
//     void OnStart() override { Action1(...); }
//   };
//
// Usage:
//   Start<SeriesOfActionsContext>(
//       ...,
//       returning_callback,
//       base::SequencedTaskRunnerHandle::Get());
//
template <typename ResponseType>
class TaskRunnerContext {
 public:
  TaskRunnerContext(const TaskRunnerContext& other) = delete;
  TaskRunnerContext& operator=(const TaskRunnerContext& other) = delete;

  // Schedules next execution (can be called from any thread).
  template <class Function, class... Args>
  void Schedule(Function&& proc, Args&&... args) {
    task_runner_->PostTask(FROM_HERE,
                           base::BindOnce(std::forward<Function>(proc),
                                          std::forward<Args>(args)...));
  }

  // Schedules next execution with delay (can be called from any thread).
  template <class Function, class... Args>
  void ScheduleAfter(base::TimeDelta delay, Function&& proc, Args&&... args) {
    task_runner_->PostDelayedTask(FROM_HERE,
                                  base::BindOnce(std::forward<Function>(proc),
                                                 std::forward<Args>(args)...),
                                  delay);
  }

  // Responds to the caller once completed the work sequence
  // (can only be called by action scheduled to the sequenced task runner).
  void Response(ResponseType result) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    OnCompletion();

    // Respond to the caller.
    DCHECK(!callback_.is_null()) << "Already responded";
    std::move(callback_).Run(std::forward<ResponseType>(result));

    // Self-destruct.
    delete this;
  }

  // Helper method checks that the caller runs on valid sequence.
  // Can be used by any scheduled action.
  // No need to call it by OnStart, OnCompletion and destructor.
  // For non-debug builds it is a no-op.
  void CheckOnValidSequence() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  }

 protected:
  // Constructor is protected, for derived class to refer to.
  TaskRunnerContext(base::OnceCallback<void(ResponseType)> callback,
                    scoped_refptr<base::SequencedTaskRunner> task_runner)
      : callback_(std::move(callback)), task_runner_(std::move(task_runner)) {
    // Constructor can be called from any thread.
    DETACH_FROM_SEQUENCE(sequence_checker_);
  }

  // Context can only be deleted by calling Response method.
  virtual ~TaskRunnerContext() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    DCHECK(callback_.is_null()) << "Deleted without responding to the caller";
  }

 private:
  template <typename ContextType /* derived from TaskRunnerContext*/,
            class... Args>
  friend void Start(Args&&... args);

  // Hook for execution start. Should be overridden to do non-trivial work.
  virtual void OnStart() { Response(ResponseType()); }

  // Finalization action before responding and deleting the context.
  // May be overridden, if necessary.
  virtual void OnCompletion() {}

  // Wrapper for OnStart to mandate sequence checker.
  void OnStartWrap() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    OnStart();
  }

  // User callback to deliver result.
  base::OnceCallback<void(ResponseType)> callback_;

  // Sequential task runner (guarantees that each action is executed
  // sequentially in order of submission).
  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  SEQUENCE_CHECKER(sequence_checker_);
};

// Constructs the context and starts execution on the assigned sequential task
// runner. Can be called from any thread to schedule the first action in the
// sequence.
template <typename ContextType /* derived from TaskRunnerContext*/,
          class... Args>
void Start(Args&&... args) {
  ContextType* const context = new ContextType(std::forward<Args>(args)...);
  // Start execution handing |context| over to the callback, in order
  // to make sure final |OnStart| (with possible |Response| and self-destruct)
  // can only happen on |task_runner|.
  context->task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&ContextType::OnStartWrap, base::Unretained(context)));
}

}  // namespace reporting

#endif  // MISSIVE_UTIL_TASK_RUNNER_CONTEXT_H_
