// 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 "media/capabilities/video_decode_stats_db_impl.h"

#include <memory>
#include <tuple>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequence_checker.h"
#include "base/task/post_task.h"
#include "base/time/default_clock.h"
#include "components/leveldb_proto/public/proto_database_provider.h"
#include "media/base/media_switches.h"
#include "media/capabilities/video_decode_stats.pb.h"

namespace media {

using ProtoDecodeStatsEntry = leveldb_proto::ProtoDatabase<DecodeStatsProto>;

namespace {

// Avoid changing client name. Used in UMA.
// See comments in components/leveldb_proto/leveldb_database.h
const char kDatabaseClientName[] = "VideoDecodeStatsDB";

const int kMaxFramesPerBufferDefault = 2500;

const int kMaxDaysToKeepStatsDefault = 30;

}  // namespace

const char VideoDecodeStatsDBImpl::kMaxFramesPerBufferParamName[] =
    "db_frames_buffer_size";

const char VideoDecodeStatsDBImpl::kMaxDaysToKeepStatsParamName[] =
    "db_days_to_keep_stats";

// static
int VideoDecodeStatsDBImpl::GetMaxFramesPerBuffer() {
  return base::GetFieldTrialParamByFeatureAsDouble(
      kMediaCapabilitiesWithParameters, kMaxFramesPerBufferParamName,
      kMaxFramesPerBufferDefault);
}

// static
int VideoDecodeStatsDBImpl::GetMaxDaysToKeepStats() {
  return base::GetFieldTrialParamByFeatureAsDouble(
      kMediaCapabilitiesWithParameters, kMaxDaysToKeepStatsParamName,
      kMaxDaysToKeepStatsDefault);
}

// static
std::unique_ptr<VideoDecodeStatsDBImpl> VideoDecodeStatsDBImpl::Create(
    base::FilePath db_dir) {
  DVLOG(2) << __func__ << " db_dir:" << db_dir;

  auto proto_db =
      leveldb_proto::ProtoDatabaseProvider::CreateUniqueDB<DecodeStatsProto>(
          base::CreateSequencedTaskRunnerWithTraits(
              {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
               base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}));

  return base::WrapUnique(
      new VideoDecodeStatsDBImpl(std::move(proto_db), db_dir));
}

constexpr char VideoDecodeStatsDBImpl::kDefaultWriteTime[];

VideoDecodeStatsDBImpl::VideoDecodeStatsDBImpl(
    std::unique_ptr<leveldb_proto::ProtoDatabase<DecodeStatsProto>> db,
    const base::FilePath& db_dir)
    : db_(std::move(db)),
      db_dir_(db_dir),
      wall_clock_(base::DefaultClock::GetInstance()),
      weak_ptr_factory_(this) {
  bool time_parsed =
      base::Time::FromString(kDefaultWriteTime, &default_write_time_);
  DCHECK(time_parsed);

  DCHECK(db_);
  DCHECK(!db_dir_.empty());
}

VideoDecodeStatsDBImpl::~VideoDecodeStatsDBImpl() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

void VideoDecodeStatsDBImpl::Initialize(InitializeCB init_cb) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(init_cb);
  DCHECK(!IsInitialized());

  // "Simple options" will use the default global cache of 8MB. In the worst
  // case our whole DB will be less than 35K, so we aren't worried about
  // spamming the cache.
  // TODO(chcunningham): Keep an eye on the size as the table evolves.
  db_->Init(kDatabaseClientName, db_dir_, leveldb_proto::CreateSimpleOptions(),
            base::BindOnce(&VideoDecodeStatsDBImpl::OnInit,
                           weak_ptr_factory_.GetWeakPtr(), std::move(init_cb)));
}

void VideoDecodeStatsDBImpl::OnInit(InitializeCB init_cb, bool success) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(2) << __func__ << (success ? " succeeded" : " FAILED!");
  UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Initialize",
                        success);

  db_init_ = true;

  // Can't use DB when initialization fails.
  if (!success)
    db_.reset();

  std::move(init_cb).Run(success);
}

bool VideoDecodeStatsDBImpl::IsInitialized() {
  // |db_| will be null if Initialization failed.
  return db_init_ && db_;
}

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

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

  db_->GetEntry(key.Serialize(),
                base::BindOnce(&VideoDecodeStatsDBImpl::WriteUpdatedEntry,
                               weak_ptr_factory_.GetWeakPtr(), key, entry,
                               std::move(append_done_cb)));
}

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

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

  db_->GetEntry(
      key.Serialize(),
      base::BindOnce(&VideoDecodeStatsDBImpl::OnGotDecodeStats,
                     weak_ptr_factory_.GetWeakPtr(), std::move(get_stats_cb)));
}

bool VideoDecodeStatsDBImpl::AreStatsExpired(
    const DecodeStatsProto* const stats_proto) {
  double last_write_date = stats_proto->last_write_date();
  if (last_write_date == 0) {
    // Set a default time if the write date is zero (no write since proto was
    // updated to include the time stamp).
    last_write_date = default_write_time_.ToJsTime();
  }

  const int kMaxDaysToKeepStats = GetMaxDaysToKeepStats();
  DCHECK_GT(kMaxDaysToKeepStats, 0);

  return wall_clock_->Now() - base::Time::FromJsTime(last_write_date) >
         base::TimeDelta::FromDays(kMaxDaysToKeepStats);
}

void VideoDecodeStatsDBImpl::WriteUpdatedEntry(
    const VideoDescKey& key,
    const DecodeStatsEntry& new_entry,
    AppendDecodeStatsCB append_done_cb,
    bool read_success,
    std::unique_ptr<DecodeStatsProto> stats_proto) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(IsInitialized());

  // Note: outcome of "Write" operation logged in OnEntryUpdated().
  UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Read",
                        read_success);

  if (!read_success) {
    DVLOG(2) << __func__ << " FAILED DB read for " << key.ToLogString()
             << "; ignoring update!";
    std::move(append_done_cb).Run(false);
    return;
  }

  if (!stats_proto || AreStatsExpired(stats_proto.get())) {
    // Default instance will have all zeros for numeric types.
    stats_proto.reset(new DecodeStatsProto());
  }

  uint64_t old_frames_decoded = stats_proto->frames_decoded();
  uint64_t old_frames_dropped = stats_proto->frames_dropped();
  uint64_t old_frames_power_efficient = stats_proto->frames_power_efficient();

  const uint64_t kMaxFramesPerBuffer = GetMaxFramesPerBuffer();
  DCHECK_GT(kMaxFramesPerBuffer, 0UL);

  if (old_frames_decoded + new_entry.frames_decoded > kMaxFramesPerBuffer) {
    // The |new_entry| is pushing out some or all of the old data. Achieve this
    // by weighting the dropped and power efficiency stats by the ratio of the
    // the buffer that new entry fills.
    double fill_ratio = std::min(
        static_cast<double>(new_entry.frames_decoded) / kMaxFramesPerBuffer,
        1.0);

    double old_dropped_ratio =
        static_cast<double>(old_frames_dropped) / old_frames_decoded;
    double old_efficient_ratio =
        static_cast<double>(old_frames_power_efficient) / old_frames_decoded;
    double new_entry_dropped_ratio =
        static_cast<double>(new_entry.frames_dropped) /
        new_entry.frames_decoded;
    double new_entry_efficient_ratio =
        static_cast<double>(new_entry.frames_power_efficient) /
        new_entry.frames_decoded;

    double agg_dropped_ratio = fill_ratio * new_entry_dropped_ratio +
                               (1 - fill_ratio) * old_dropped_ratio;
    double agg_efficient_ratio = fill_ratio * new_entry_efficient_ratio +
                                 (1 - fill_ratio) * old_efficient_ratio;

    stats_proto->set_frames_decoded(kMaxFramesPerBuffer);
    stats_proto->set_frames_dropped(
        std::round(agg_dropped_ratio * kMaxFramesPerBuffer));
    stats_proto->set_frames_power_efficient(
        std::round(agg_efficient_ratio * kMaxFramesPerBuffer));
  } else {
    // Adding |new_entry| does not exceed |kMaxFramesPerfBuffer|. Simply sum the
    // stats.
    stats_proto->set_frames_decoded(new_entry.frames_decoded +
                                    old_frames_decoded);
    stats_proto->set_frames_dropped(new_entry.frames_dropped +
                                    old_frames_dropped);
    stats_proto->set_frames_power_efficient(new_entry.frames_power_efficient +
                                            old_frames_power_efficient);
  }

  // Update the time stamp for the current write.
  stats_proto->set_last_write_date(wall_clock_->Now().ToJsTime());

  // Push the update to the DB.
  using DBType = leveldb_proto::ProtoDatabase<DecodeStatsProto>;
  std::unique_ptr<DBType::KeyEntryVector> entries =
      std::make_unique<DBType::KeyEntryVector>();
  entries->emplace_back(key.Serialize(), *stats_proto);
  db_->UpdateEntries(std::move(entries),
                     std::make_unique<leveldb_proto::KeyVector>(),
                     base::BindOnce(&VideoDecodeStatsDBImpl::OnEntryUpdated,
                                    weak_ptr_factory_.GetWeakPtr(),
                                    std::move(append_done_cb)));
}

void VideoDecodeStatsDBImpl::OnEntryUpdated(AppendDecodeStatsCB append_done_cb,
                                            bool success) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Write", success);
  DVLOG(3) << __func__ << " update " << (success ? "succeeded" : "FAILED!");
  std::move(append_done_cb).Run(success);
}

void VideoDecodeStatsDBImpl::OnGotDecodeStats(
    GetDecodeStatsCB get_stats_cb,
    bool success,
    std::unique_ptr<DecodeStatsProto> stats_proto) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Read", success);

  std::unique_ptr<DecodeStatsEntry> entry;

  if (stats_proto && !AreStatsExpired(stats_proto.get())) {
    DCHECK(success);

    entry = std::make_unique<DecodeStatsEntry>(
        stats_proto->frames_decoded(), stats_proto->frames_dropped(),
        stats_proto->frames_power_efficient());
  }

  DVLOG(3) << __func__ << " read " << (success ? "succeeded" : "FAILED!")
           << " entry: " << (entry ? entry->ToLogString() : "nullptr");

  std::move(get_stats_cb).Run(success, std::move(entry));
}

void VideoDecodeStatsDBImpl::ClearStats(base::OnceClosure clear_done_cb) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(2) << __func__;

  db_->LoadKeys(
      base::BindOnce(&VideoDecodeStatsDBImpl::OnLoadAllKeysForClearing,
                     weak_ptr_factory_.GetWeakPtr(), std::move(clear_done_cb)));
}

void VideoDecodeStatsDBImpl::OnLoadAllKeysForClearing(
    base::OnceClosure clear_done_cb,
    bool success,
    std::unique_ptr<std::vector<std::string>> keys) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(2) << __func__ << (success ? " succeeded" : " FAILED!");

  UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.LoadKeys", success);

  if (success) {
    // Remove all keys.
    db_->UpdateEntries(
        std::make_unique<ProtoDecodeStatsEntry::KeyEntryVector>(),
        std::move(keys) /* keys_to_remove */,
        base::BindOnce(&VideoDecodeStatsDBImpl::OnStatsCleared,
                       weak_ptr_factory_.GetWeakPtr(),
                       std::move(clear_done_cb)));
  } else {
    // Fail silently. See comment in OnStatsCleared().
    std::move(clear_done_cb).Run();
  }
}

void VideoDecodeStatsDBImpl::OnStatsCleared(base::OnceClosure clear_done_cb,
                                            bool success) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(2) << __func__ << (success ? " succeeded" : " FAILED!");

  UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Destroy", success);

  // We don't pass success to |clear_done_cb|. Clearing is best effort and
  // there is no additional action for callers to take in case of failure.
  // TODO(chcunningham): Monitor UMA and consider more aggressive action like
  // deleting the DB directory.
  std::move(clear_done_cb).Run();
}

}  // namespace media
