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

#include "components/download/internal/common/download_db_cache.h"

#include "base/functional/bind.h"
#include "base/task/sequenced_task_runner.h"
#include "components/download/database/download_db.h"
#include "components/download/database/download_db_conversions.h"
#include "components/download/database/download_db_entry.h"
#include "components/download/public/common/download_features.h"
#include "components/download/public/common/download_item_impl.h"
#include "components/download/public/common/download_stats.h"
#include "components/download/public/common/download_utils.h"

namespace download {

namespace {

// Interval between download DB updates.
// TODO(qinmin): make this finch configurable.
const int kUpdateDBIntervalMs = 10000;

enum class ShouldUpdateDownloadDBResult {
  NO_UPDATE,
  UPDATE,
  UPDATE_IMMEDIATELY,
};

ShouldUpdateDownloadDBResult ShouldUpdateDownloadDB(
    std::optional<DownloadDBEntry> previous,
    const DownloadDBEntry& current) {
  if (!previous)
    return ShouldUpdateDownloadDBResult::UPDATE_IMMEDIATELY;

  std::optional<InProgressInfo> previous_info;
  if (previous->download_info)
    previous_info = previous->download_info->in_progress_info;
  base::FilePath previous_path =
      previous_info ? previous_info->current_path : base::FilePath();

  bool previous_paused = previous_info && previous_info->paused;

  std::optional<InProgressInfo> current_info;
  if (current.download_info)
    current_info = current.download_info->in_progress_info;

  base::FilePath current_path;
  bool paused = false;
  GURL url;
  DownloadItem::DownloadState state = DownloadItem::DownloadState::IN_PROGRESS;
  DownloadInterruptReason interrupt_reason = DOWNLOAD_INTERRUPT_REASON_NONE;
  if (current_info) {
    current_path = current_info->current_path;
    paused = current_info->paused;
    if (!current_info->url_chain.empty())
      url = current_info->url_chain.back();
    state = current_info->state;
    interrupt_reason = current_info->interrupt_reason;
  }

  // When download path is determined, Chrome should commit the history
  // immediately. Otherwise the file will be left permanently on the external
  // storage if Chrome crashes right away.
  if (current_path != previous_path || paused != previous_paused) {
    return ShouldUpdateDownloadDBResult::UPDATE_IMMEDIATELY;
  }

  if (previous.value() == current)
    return ShouldUpdateDownloadDBResult::NO_UPDATE;

  if (IsDownloadDone(url, state, interrupt_reason))
    return ShouldUpdateDownloadDBResult::UPDATE_IMMEDIATELY;

  return ShouldUpdateDownloadDBResult::UPDATE;
}

void CleanUpInProgressEntry(DownloadDBEntry* entry) {
  if (!entry->download_info)
    return;

  std::optional<InProgressInfo>& in_progress_info =
      entry->download_info->in_progress_info;
  if (!in_progress_info)
    return;

  if (in_progress_info->state == DownloadItem::DownloadState::IN_PROGRESS) {
    in_progress_info->state = DownloadItem::DownloadState::INTERRUPTED;
    in_progress_info->interrupt_reason =
        download::DOWNLOAD_INTERRUPT_REASON_CRASH;
    // We should not trust the hash value for crashed in-progress download, as
    // hash is not calculated for when download is in progress.
    in_progress_info->hash = std::string();
  }
}

void OnDownloadDBUpdated(bool success) {
  // TODO(qinmin): handle the case that update fails.
  if (!success)
    LOG(ERROR) << "Unable to update DB entries";
}

// Check if a DownloadDBEntry represents an in progress download.
bool IsInProgressEntry(std::optional<DownloadDBEntry> entry) {
  if (!entry || !entry->download_info ||
      !entry->download_info->in_progress_info)
    return false;

  return entry->download_info->in_progress_info->state ==
         DownloadItem::DownloadState::IN_PROGRESS;
}

}  // namespace

DownloadDBCache::DownloadDBCache(std::unique_ptr<DownloadDB> download_db)
    : initialized_(false), download_db_(std::move(download_db)) {
  DCHECK(download_db_);
}

DownloadDBCache::~DownloadDBCache() = default;

void DownloadDBCache::Initialize(InitializeCallback callback) {
  DCHECK(!initialized_);
  download_db_->Initialize(
      base::BindOnce(&DownloadDBCache::OnDownloadDBInitialized,
                     weak_factory_.GetWeakPtr(), std::move(callback)));
}

std::optional<DownloadDBEntry> DownloadDBCache::RetrieveEntry(
    const std::string& guid) {
  auto iter = cached_entries_.find(guid);
  if (iter != cached_entries_.end())
    return iter->second;
  return std::nullopt;
}

void DownloadDBCache::AddOrReplaceEntry(const DownloadDBEntry& entry) {
  if (!entry.download_info)
    return;
  const std::string& guid = entry.download_info->guid;
  ShouldUpdateDownloadDBResult result =
      ShouldUpdateDownloadDB(RetrieveEntry(guid), entry);
  if (result == ShouldUpdateDownloadDBResult::NO_UPDATE)
    return;
  if (!update_timer_.IsRunning() &&
      result == ShouldUpdateDownloadDBResult::UPDATE) {
    update_timer_.Start(FROM_HERE, base::Milliseconds(kUpdateDBIntervalMs),
                        this, &DownloadDBCache::UpdateDownloadDB);
  }

  cached_entries_[guid] = entry;
  updated_guids_.emplace(guid);
  if (result == ShouldUpdateDownloadDBResult::UPDATE_IMMEDIATELY) {
    UpdateDownloadDB();
    update_timer_.Stop();
  }
}

void DownloadDBCache::RemoveEntry(const std::string& guid) {
  cached_entries_.erase(guid);
  updated_guids_.erase(guid);
  if (initialized_)
    download_db_->Remove(guid);
}

void DownloadDBCache::UpdateDownloadDB() {
  if (updated_guids_.empty())
    return;

  std::vector<DownloadDBEntry> entries;
  for (const auto& guid : updated_guids_) {
    std::optional<DownloadDBEntry> entry = RetrieveEntry(guid);
    DCHECK(entry);
    entries.emplace_back(entry.value());
    // If the entry is no longer in-progress, remove it from the cache as it may
    // not update again soon.
    if (!IsInProgressEntry(entry))
      cached_entries_.erase(guid);
  }
  updated_guids_.clear();
  if (initialized_) {
    download_db_->AddOrReplaceEntries(entries,
                                      base::BindOnce(&OnDownloadDBUpdated));
  }
}

void DownloadDBCache::OnDownloadUpdated(DownloadItem* download) {
  DownloadDBEntry entry = CreateDownloadDBEntryFromItem(
      *(static_cast<DownloadItemImpl*>(download)));
  AddOrReplaceEntry(entry);
}

void DownloadDBCache::OnDownloadRemoved(DownloadItem* download) {
  RemoveEntry(download->GetGuid());
}

void DownloadDBCache::OnDownloadDBInitialized(
    InitializeCallback callback,
    bool success) {
  if (success) {
    download_db_->LoadEntries(
        base::BindOnce(&DownloadDBCache::OnDownloadDBEntriesLoaded,
                       weak_factory_.GetWeakPtr(), std::move(callback)));
  } else {
    std::move(callback).Run(false,
                            std::make_unique<std::vector<DownloadDBEntry>>());
  }
}

void DownloadDBCache::OnDownloadDBEntriesLoaded(
    InitializeCallback callback,
    bool success,
    std::unique_ptr<std::vector<DownloadDBEntry>> entries) {
  initialized_ = success;
  for (auto& entry : *entries) {
    // If the entry is from the metadata cache migration, just remove it from
    // DB as the data is not being cleaned up properly.
    if (entry.download_info->id < 0)
      RemoveEntry(entry.download_info->guid);
    else
      CleanUpInProgressEntry(&entry);
  }
  std::move(callback).Run(success, std::move(entries));
}

void DownloadDBCache::SetTimerTaskRunnerForTesting(
    scoped_refptr<base::SequencedTaskRunner> task_runner) {
  update_timer_.SetTaskRunner(task_runner);
}

}  //  namespace download
