// 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 "chrome/browser/download/download_status_updater.h"

#include <stdint.h>

#include <vector>

#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/profile.h"

namespace {

// DownloadStatusUpdater::UpdateAppIconDownloadProgress() expects to only be
// called once when a DownloadItem completes, then not again (except perhaps
// until it is resumed). The existence of WasInProgressData is effectively a
// boolean that indicates whether that final UpdateAppIconDownloadProgress()
// call has been made for a given DownloadItem. It is expected that there will
// be many more non-in-progress downloads than in-progress downloads, so
// WasInProgressData is set for in-progress downloads and cleared from
// non-in-progress downloads instead of the other way around in order to save
// memory.
class WasInProgressData : public base::SupportsUserData::Data {
 public:
  static bool Get(download::DownloadItem* item) {
    return item->GetUserData(kKey) != nullptr;
  }

  static void Clear(download::DownloadItem* item) {
    item->RemoveUserData(kKey);
  }

  explicit WasInProgressData(download::DownloadItem* item) {
    item->SetUserData(kKey, base::WrapUnique(this));
  }

  WasInProgressData(const WasInProgressData&) = delete;
  WasInProgressData& operator=(const WasInProgressData&) = delete;

 private:
  static const char kKey[];
};

const char WasInProgressData::kKey[] =
  "DownloadItem DownloadStatusUpdater WasInProgressData";

}  // anonymous namespace

DownloadStatusUpdater::DownloadStatusUpdater() = default;

DownloadStatusUpdater::~DownloadStatusUpdater() = default;

bool DownloadStatusUpdater::GetProgress(float* progress,
                                        int* download_count) const {
  *progress = 0;
  *download_count = 0;
  bool progress_certain = true;
  int64_t received_bytes = 0;
  int64_t total_bytes = 0;

  for (const auto& notifier : notifiers_) {
    if (notifier->GetManager()) {
      content::DownloadManager::DownloadVector items;
      notifier->GetManager()->GetAllDownloads(&items);
      for (download::DownloadItem* item : items) {
        if (item->GetState() == download::DownloadItem::IN_PROGRESS) {
          ++*download_count;
          if (item->GetTotalBytes() <= 0) {
            // There may or may not be more data coming down this pipe.
            progress_certain = false;
          } else {
            received_bytes += item->GetReceivedBytes();
            total_bytes += item->GetTotalBytes();
          }
        }
      }
    }
  }

  if (total_bytes > 0)
    *progress = static_cast<float>(received_bytes) / total_bytes;
  return progress_certain;
}

void DownloadStatusUpdater::AddManager(content::DownloadManager* manager) {
  notifiers_.push_back(
      std::make_unique<download::AllDownloadItemNotifier>(manager, this));
  content::DownloadManager::DownloadVector items;
  manager->GetAllDownloads(&items);
  for (download::DownloadItem* item : items) {
    OnDownloadCreated(manager, item);
  }
}

void DownloadStatusUpdater::OnDownloadCreated(content::DownloadManager* manager,
                                              download::DownloadItem* item) {
  // Ignore downloads loaded from history, which are in a terminal state.
  // TODO(benjhayden): Use the Observer interface to distinguish between
  // historical and started downloads.
  if (item->GetState() == download::DownloadItem::IN_PROGRESS &&
      !item->IsTransient()) {
    UpdateAppIconDownloadProgress(item);
    new WasInProgressData(item);
  }
  // else, the lack of WasInProgressData indicates to OnDownloadUpdated that it
  // should not call UpdateAppIconDownloadProgress().
}

void DownloadStatusUpdater::OnDownloadUpdated(content::DownloadManager* manager,
                                              download::DownloadItem* item) {
  if (item->GetState() == download::DownloadItem::IN_PROGRESS &&
      !item->IsTransient()) {
    // If the item was interrupted/cancelled and then resumed/restarted, then
    // set WasInProgress so that UpdateAppIconDownloadProgress() will be called
    // when it completes.
    if (!WasInProgressData::Get(item))
      new WasInProgressData(item);
  } else {
    // The item is now in a terminal state. If it was already in a terminal
    // state, then do not call UpdateAppIconDownloadProgress() again. If it is
    // now transitioning to a terminal state, then clear its WasInProgressData
    // so that UpdateAppIconDownloadProgress() won't be called after this final
    // call.
    if (!WasInProgressData::Get(item))
      return;
    WasInProgressData::Clear(item);
  }
  UpdateAppIconDownloadProgress(item);
  UpdateProfileKeepAlive(manager);
}

void DownloadStatusUpdater::OnManagerGoingDown(
    content::DownloadManager* manager) {
  Profile* profile = Profile::FromBrowserContext(manager->GetBrowserContext());
  profile_keep_alives_.erase(profile);
}

void DownloadStatusUpdater::UpdateProfileKeepAlive(
    content::DownloadManager* manager) {
  if (!manager) {
    // Can be null in tests.
    return;
  }

  Profile* profile = Profile::FromBrowserContext(manager->GetBrowserContext());
  DCHECK(profile);
  if (profile->IsOffTheRecord())
    return;

  // Are we already holding a keepalive?
  bool already_has_keep_alive =
      (profile_keep_alives_.find(profile) != profile_keep_alives_.end());

  // Do we still need to hold a keepalive?
  content::DownloadManager::DownloadVector items;
  manager->GetAllDownloads(&items);
  auto items_it = std::ranges::find(items, download::DownloadItem::IN_PROGRESS,
                                    &download::DownloadItem::GetState);
  bool should_keep_alive = (items_it != items.end());

  if (should_keep_alive == already_has_keep_alive) {
    // The current state is already correct for this Profile. No changes needed.
    return;
  }

  // The current state is incorrect. Acquire/release a keepalive.
  if (should_keep_alive) {
    profile_keep_alives_[profile] = std::make_unique<ScopedProfileKeepAlive>(
        profile, ProfileKeepAliveOrigin::kDownloadInProgress);
  } else {
    profile_keep_alives_.erase(profile);
  }
}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
void DownloadStatusUpdater::UpdateAppIconDownloadProgress(
    download::DownloadItem* download) {
  // TODO(avi): Implement for Android?
}
#endif
