// Copyright 2018 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 "media/capabilities/in_memory_video_decode_stats_db_impl.h"

#include <memory>
#include <tuple>

#include "base/files/file_path.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequence_checker.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "media/base/bind_to_current_loop.h"
#include "media/capabilities/video_decode_stats_db_impl.h"
#include "media/capabilities/video_decode_stats_db_provider.h"

namespace media {

InMemoryVideoDecodeStatsDBImpl::InMemoryVideoDecodeStatsDBImpl(
    VideoDecodeStatsDBProvider* seed_db_provider)
    : seed_db_provider_(seed_db_provider), weak_ptr_factory_(this) {
  DVLOG(2) << __func__;
}

InMemoryVideoDecodeStatsDBImpl::~InMemoryVideoDecodeStatsDBImpl() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (seed_db_)
    seed_db_->set_dependent_db(nullptr);
}

void InMemoryVideoDecodeStatsDBImpl::Initialize(InitializeCB init_cb) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(init_cb);
  DCHECK(!db_init_);

  // Fetch an *initialized* seed DB.
  if (seed_db_provider_) {
    seed_db_provider_->GetVideoDecodeStatsDB(
        base::BindOnce(&InMemoryVideoDecodeStatsDBImpl::OnGotSeedDB,
                       weak_ptr_factory_.GetWeakPtr(), std::move(init_cb)));
  } else {
    // No seed DB provider (e.g. guest session) means no work to do.
    DVLOG(2) << __func__ << " NO seed db";
    db_init_ = true;

    // Bind to avoid reentrancy.
    std::move(BindToCurrentLoop(std::move(init_cb))).Run(true);
  }
}

void InMemoryVideoDecodeStatsDBImpl::OnGotSeedDB(InitializeCB init_cb,
                                                 VideoDecodeStatsDB* db) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(2) << __func__ << (db ? " has" : " null") << " seed db";

  db_init_ = true;

  CHECK(!seed_db_) << __func__ << " Already have a seed_db_?";
  seed_db_ = db;

  if (seed_db_)
    seed_db_->set_dependent_db(this);

  // Hard coding success = true. There are rare cases (e.g. disk corruption)
  // where an incognito profile may fail to acquire a reference to the base
  // profile's DB. But this just means incognito is in the same boat as guest
  // profiles (never have a seed DB) and is not a show stopper.
  std::move(init_cb).Run(true);
}

void InMemoryVideoDecodeStatsDBImpl::AppendDecodeStats(
    const VideoDescKey& key,
    const DecodeStatsEntry& entry,
    AppendDecodeStatsCB append_done_cb) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(db_init_);

  DVLOG(3) << __func__ << " Reading key " << key.ToLogString()
           << " from DB with intent to update with " << entry.ToLogString();

  auto it = in_memory_db_.find(key.Serialize());
  if (it == in_memory_db_.end()) {
    if (seed_db_) {
      // |seed_db_| exists and no in-memory entry is found for this key, means
      // we haven't checked the |seed_db_| yet. Query |seed_db_| and append new
      // stats to any seed values.
      seed_db_->GetDecodeStats(
          key, base::BindOnce(
                   &InMemoryVideoDecodeStatsDBImpl::CompleteAppendWithSeedData,
                   weak_ptr_factory_.GetWeakPtr(), key, entry,
                   std::move(append_done_cb)));
      return;
    }

    // Otherwise, these are the first stats for this key. Add a a copy of
    // |entry| to the database.
    in_memory_db_.emplace(key.Serialize(), entry);
  } else {
    // We've already asked the |seed_db_| for its data. Just add the new stats
    // to our local copy via the iterators reference.
    it->second += entry;
  }

  // Bind to avoid reentrancy.
  std::move(BindToCurrentLoop(std::move(append_done_cb))).Run(true);
}

void InMemoryVideoDecodeStatsDBImpl::GetDecodeStats(
    const VideoDescKey& key,
    GetDecodeStatsCB get_stats_cb) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(db_init_);

  DVLOG(3) << __func__ << " " << key.ToLogString();

  auto it = in_memory_db_.find(key.Serialize());
  if (it == in_memory_db_.end()) {
    if (seed_db_) {
      // |seed_db_| exists and no in-memory entry is found for this key, means
      // we haven't checked the |seed_db_| yet.
      seed_db_->GetDecodeStats(
          key, base::BindOnce(&InMemoryVideoDecodeStatsDBImpl::OnGotSeedEntry,
                              weak_ptr_factory_.GetWeakPtr(), key,
                              std::move(get_stats_cb)));
    } else {
      // No seed data. Return an empty entry. Bind to avoid reentrancy.
      std::move(BindToCurrentLoop(std::move(get_stats_cb)))
          .Run(true, std::make_unique<DecodeStatsEntry>(0, 0, 0));
    }
  } else {
    // Return whatever what we found. Bind to avoid reentrancy.
    std::move(BindToCurrentLoop(std::move(get_stats_cb)))
        .Run(true, std::make_unique<DecodeStatsEntry>(it->second));
  }
}

void InMemoryVideoDecodeStatsDBImpl::CompleteAppendWithSeedData(
    const VideoDescKey& key,
    const DecodeStatsEntry& entry,
    AppendDecodeStatsCB append_done_cb,
    bool read_success,
    std::unique_ptr<DecodeStatsEntry> seed_entry) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(db_init_);

  if (!read_success) {
    // Not a show stopper. Log it and carry on as if the seed DB were empty.
    DVLOG(2) << __func__ << " FAILED seed DB read for " << key.ToLogString();
    DCHECK(!seed_entry);
  }

  if (!seed_entry)
    seed_entry = std::make_unique<DecodeStatsEntry>(0, 0, 0);

  // Add new stats to the seed entry and store in memory.
  *seed_entry += entry;
  in_memory_db_.emplace(key.Serialize(), *seed_entry);

  DVLOG(3) << __func__ << " Updating " << key.ToLogString() << " with "
           << entry.ToLogString() << " aggregate:" << seed_entry->ToLogString();

  std::move(append_done_cb).Run(true);
}

void InMemoryVideoDecodeStatsDBImpl::OnGotSeedEntry(
    const VideoDescKey& key,
    GetDecodeStatsCB get_stats_cb,
    bool success,
    std::unique_ptr<DecodeStatsEntry> seed_entry) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Failure is not a show stopper. Just a debug log...
  DVLOG(3) << __func__ << " read " << (success ? "succeeded" : "FAILED!")
           << " entry: " << (seed_entry ? seed_entry->ToLogString() : "null");

  if (!seed_entry)
    seed_entry = std::make_unique<DecodeStatsEntry>(0, 0, 0);

  // Always write to |in_memory_db_| to avoid querying |seed_db_| for this key
  // going forward.
  in_memory_db_.emplace(key.Serialize(), *seed_entry);

  std::move(get_stats_cb).Run(true, std::move(seed_entry));
}

void InMemoryVideoDecodeStatsDBImpl::ClearStats(
    base::OnceClosure destroy_done_cb) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(2) << __func__;

  // Really, this is not reachable code because user's can't clear the history
  // for a guest/incognito account. But if that ever changes, the reasonable
  // thing is to wipe only the |in_memory_db_|. |seed_db_| can be cleared by the
  // profile that owns it.
  in_memory_db_.clear();

  // Bind to avoid reentrancy.
  std::move(BindToCurrentLoop(std::move(destroy_done_cb))).Run();
}

}  // namespace media
