// Copyright 2017 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.

#include "components/offline_items_collection/core/throttled_offline_content_provider.h"

#include <utility>

#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/offline_items_collection/core/offline_item.h"

namespace offline_items_collection {
namespace {
const int kDelayBetweenUpdatesMs = 1000;
}  // namespace

ThrottledOfflineContentProvider::ThrottledOfflineContentProvider(
    OfflineContentProvider* provider)
    : ThrottledOfflineContentProvider(
          base::TimeDelta::FromMilliseconds(kDelayBetweenUpdatesMs),
          provider) {}

ThrottledOfflineContentProvider::ThrottledOfflineContentProvider(
    const base::TimeDelta& delay_between_updates,
    OfflineContentProvider* provider)
    : delay_between_updates_(delay_between_updates),
      last_update_time_(base::TimeTicks::Now()),
      update_queued_(false),
      wrapped_provider_(provider) {
  DCHECK(wrapped_provider_);
  wrapped_provider_->AddObserver(this);
}

ThrottledOfflineContentProvider::~ThrottledOfflineContentProvider() {
  wrapped_provider_->RemoveObserver(this);
}

void ThrottledOfflineContentProvider::OpenItem(LaunchLocation location,
                                               const ContentId& id) {
  wrapped_provider_->OpenItem(location, id);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::RemoveItem(const ContentId& id) {
  wrapped_provider_->RemoveItem(id);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::CancelDownload(const ContentId& id) {
  wrapped_provider_->CancelDownload(id);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::PauseDownload(const ContentId& id) {
  wrapped_provider_->PauseDownload(id);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::ResumeDownload(const ContentId& id,
                                                     bool has_user_gesture) {
  wrapped_provider_->ResumeDownload(id, has_user_gesture);
  FlushUpdates();
}

void ThrottledOfflineContentProvider::GetItemById(const ContentId& id,
                                                  SingleItemCallback callback) {
  wrapped_provider_->GetItemById(
      id, base::BindOnce(&ThrottledOfflineContentProvider::OnGetItemByIdDone,
                         weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

void ThrottledOfflineContentProvider::GetAllItems(
    MultipleItemCallback callback) {
  wrapped_provider_->GetAllItems(
      base::BindOnce(&ThrottledOfflineContentProvider::OnGetAllItemsDone,
                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

void ThrottledOfflineContentProvider::OnGetAllItemsDone(
    MultipleItemCallback callback,
    const OfflineItemList& items) {
  for (const auto item : items)
    UpdateItemIfPresent(item);
  std::move(callback).Run(items);
}

void ThrottledOfflineContentProvider::OnGetItemByIdDone(
    SingleItemCallback callback,
    const base::Optional<OfflineItem>& item) {
  if (item.has_value())
    UpdateItemIfPresent(item.value());
  std::move(callback).Run(item);
}

void ThrottledOfflineContentProvider::GetVisualsForItem(
    const ContentId& id,
    GetVisualsOptions options,
    VisualsCallback callback) {
  wrapped_provider_->GetVisualsForItem(id, options, std::move(callback));
}

void ThrottledOfflineContentProvider::GetShareInfoForItem(
    const ContentId& id,
    ShareCallback callback) {
  wrapped_provider_->GetShareInfoForItem(id, std::move(callback));
}

void ThrottledOfflineContentProvider::RenameItem(const ContentId& id,
                                                 const std::string& name,
                                                 RenameCallback callback) {
  wrapped_provider_->RenameItem(id, name, std::move(callback));
}

void ThrottledOfflineContentProvider::AddObserver(
    OfflineContentProvider::Observer* observer) {
  DCHECK(observer);
  observers_.AddObserver(observer);
}

void ThrottledOfflineContentProvider::RemoveObserver(
    OfflineContentProvider::Observer* observer) {
  observers_.RemoveObserver(observer);
}

void ThrottledOfflineContentProvider::OnItemsAdded(
    const OfflineItemList& items) {
  for (auto& observer : observers_)
    observer.OnItemsAdded(items);
}

void ThrottledOfflineContentProvider::OnItemRemoved(const ContentId& id) {
  updates_.erase(id);
  for (auto& observer : observers_)
    observer.OnItemRemoved(id);
}

void ThrottledOfflineContentProvider::OnItemUpdated(
    const OfflineItem& item,
    const base::Optional<UpdateDelta>& update_delta) {
  base::Optional<UpdateDelta> merged = update_delta;
  if (updates_.find(item.id) != updates_.end()) {
    merged = UpdateDelta::MergeUpdates(updates_[item.id].second, update_delta);
  }
  updates_[item.id] = std::make_pair(item, merged);

  // If we already queued an update, we're throttling, just wait until the
  // update passes through.
  if (update_queued_)
    return;

  // If we haven't sent an update recently, let the update go through.
  base::TimeDelta current_delay = base::TimeTicks::Now() - last_update_time_;
  if (current_delay >= delay_between_updates_) {
    FlushUpdates();
    return;
  }

  // Queue the update so we wait for the proper amount of time before notifying
  // observers.
  update_queued_ = true;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&ThrottledOfflineContentProvider::FlushUpdates,
                     weak_ptr_factory_.GetWeakPtr()),
      delay_between_updates_ - current_delay);
}

void ThrottledOfflineContentProvider::UpdateItemIfPresent(
    const OfflineItem& item) {
  auto it = updates_.find(item.id);
  if (it != updates_.end())
    it->second.first = item;
}

void ThrottledOfflineContentProvider::FlushUpdates() {
  last_update_time_ = base::TimeTicks::Now();
  update_queued_ = false;

  OfflineItemMap updates = std::move(updates_);
  for (auto item_pair : updates) {
    auto& item = item_pair.second.first;
    auto& update = item_pair.second.second;
    for (auto& observer : observers_)
      observer.OnItemUpdated(item, update);
  }
}

}  // namespace offline_items_collection
