// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/dns/serial_worker.h"

#include <memory>
#include <utility>

#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/notreached.h"
#include "base/task/thread_pool.h"
#include "base/timer/timer.h"
#include "net/base/backoff_entry.h"

namespace net {

namespace {
// Default retry configuration. Only in effect if |max_number_of_retries| is
// greater than 0.
constexpr BackoffEntry::Policy kDefaultBackoffPolicy = {
    0,     // Number of initial errors to ignore without backoff.
    5000,  // Initial delay for backoff in ms: 5 seconds.
    2,     // Factor to multiply for exponential backoff.
    0,     // Fuzzing percentage.
    -1,    // No maximum delay.
    -1,    // Don't discard entry.
    false  // Don't use initial delay unless the last was an error.
};
}  // namespace

namespace {
std::unique_ptr<SerialWorker::WorkItem> DoWork(
    std::unique_ptr<SerialWorker::WorkItem> work_item) {
  DCHECK(work_item);
  work_item->DoWork();
  return work_item;
}
}  // namespace

void SerialWorker::WorkItem::FollowupWork(base::OnceClosure closure) {
  std::move(closure).Run();
}

SerialWorker::SerialWorker(int max_number_of_retries,
                           const net::BackoffEntry::Policy* backoff_policy)
    : max_number_of_retries_(max_number_of_retries),
      backoff_entry_(backoff_policy ? backoff_policy : &kDefaultBackoffPolicy) {
}

SerialWorker::~SerialWorker() = default;

void SerialWorker::WorkNow() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // Not a retry; reset failure count and cancel the pending retry (if any).
  backoff_entry_.Reset();
  retry_timer_.Stop();
  WorkNowInternal();
}

void SerialWorker::WorkNowInternal() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  switch (state_) {
    case State::kIdle:
      // We are posting weak pointer to OnWorkJobFinished to avoid a leak when
      // PostTaskAndReply fails to post task back to the original
      // task runner. In this case the callback is not destroyed, and the
      // weak reference allows SerialWorker instance to be deleted.
      base::ThreadPool::PostTaskAndReplyWithResult(
          FROM_HERE,
          {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
          base::BindOnce(&DoWork, CreateWorkItem()),
          base::BindOnce(&SerialWorker::OnDoWorkFinished, AsWeakPtr()));
      state_ = State::kWorking;
      return;
    case State::kWorking:
      // Remember to re-read after `DoWork()` finishes.
      state_ = State::kPending;
      return;
    case State::kCancelled:
    case State::kPending:
      return;
  }
}

void SerialWorker::Cancel() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  state_ = State::kCancelled;
}

void SerialWorker::OnDoWorkFinished(std::unique_ptr<WorkItem> work_item) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  switch (state_) {
    case State::kCancelled:
      return;
    case State::kWorking: {
      WorkItem* work_item_ptr = work_item.get();
      work_item_ptr->FollowupWork(
          base::BindOnce(&SerialWorker::OnFollowupWorkFinished,
                         weak_factory_.GetWeakPtr(), std::move(work_item)));
      return;
    }
    case State::kPending: {
      RerunWork(std::move(work_item));
      return;
    }
    default:
      NOTREACHED() << "Unexpected state " << static_cast<int>(state_);
  }
}

void SerialWorker::OnFollowupWorkFinished(std::unique_ptr<WorkItem> work_item) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  switch (state_) {
    case State::kCancelled:
      return;
    case State::kWorking:
      state_ = State::kIdle;
      if (OnWorkFinished(std::move(work_item)) ||
          backoff_entry_.failure_count() >= max_number_of_retries_) {
        backoff_entry_.Reset();
      } else {
        backoff_entry_.InformOfRequest(/*succeeded=*/false);

        // Try again after a delay.
        retry_timer_.Start(FROM_HERE, backoff_entry_.GetTimeUntilRelease(),
                           this, &SerialWorker::WorkNowInternal);
      }
      return;
    case State::kPending:
      RerunWork(std::move(work_item));
      return;
    default:
      NOTREACHED() << "Unexpected state " << static_cast<int>(state_);
  }
}

void SerialWorker::RerunWork(std::unique_ptr<WorkItem> work_item) {
  // `WorkNow()` was retriggered while working, so need to redo work
  // immediately to ensure up-to-date results. Reuse `work_item` rather than
  // returning it to the derived class (and letting it potentially act on a
  // potential obsolete result).
  DCHECK_EQ(state_, State::kPending);
  state_ = State::kWorking;
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE,
      {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
      base::BindOnce(&DoWork, std::move(work_item)),
      base::BindOnce(&SerialWorker::OnDoWorkFinished, AsWeakPtr()));
}

const BackoffEntry& SerialWorker::GetBackoffEntryForTesting() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return backoff_entry_;
}

const base::OneShotTimer& SerialWorker::GetRetryTimerForTesting() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return retry_timer_;
}

base::WeakPtr<SerialWorker> SerialWorker::AsWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

}  // namespace net
