// Copyright (c) 2012 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 "chrome/browser/download/download_status_updater.h"

#include <stdint.h>

#include <vector>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"

#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
#include "ui/views/linux_ui/linux_ui.h"
#endif

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) != NULL;
  }

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

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

 private:
  static const char kKey[];
  DISALLOW_COPY_AND_ASSIGN(WasInProgressData);
};

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

}  // anonymous namespace

DownloadStatusUpdater::DownloadStatusUpdater() {
}

DownloadStatusUpdater::~DownloadStatusUpdater() {
}

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 (auto* 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 (auto* 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) {
    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) {
    // 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);
}

#if defined(OS_ANDROID) || (defined(USE_AURA) && !defined(OS_WIN))
void DownloadStatusUpdater::UpdateAppIconDownloadProgress(
    download::DownloadItem* download) {
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
  const views::LinuxUI* linux_ui = views::LinuxUI::instance();
  if (linux_ui) {
    float progress = 0;
    int download_count = 0;
    GetProgress(&progress, &download_count);
    linux_ui->SetDownloadCount(download_count);
    linux_ui->SetProgressFraction(progress);
  }
#endif
  // TODO(avi): Implement for Android?
}
#endif
