// 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 <memory>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/test/scoped_task_environment.h"
#include "media/capabilities/in_memory_video_decode_stats_db_impl.h"
#include "media/capabilities/video_decode_stats_db_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::Eq;
using testing::Pointee;
using testing::IsNull;

namespace media {

static VideoDecodeStatsDB::VideoDescKey kTestKey() {
  return VideoDecodeStatsDB::VideoDescKey::MakeBucketedKey(
      VP9PROFILE_PROFILE3, gfx::Size(1024, 768), 60);
}

static VideoDecodeStatsDB::DecodeStatsEntry kEmtpyEntry() {
  return VideoDecodeStatsDB::DecodeStatsEntry(0, 0, 0);
}

class MockSeedDB : public VideoDecodeStatsDB {
 public:
  MockSeedDB() = default;
  ~MockSeedDB() override = default;

  MOCK_METHOD1(Initialize, void(InitializeCB init_cb));
  MOCK_METHOD3(AppendDecodeStats,
               void(const VideoDescKey& key,
                    const DecodeStatsEntry& entry,
                    AppendDecodeStatsCB append_done_cb));
  MOCK_METHOD2(GetDecodeStats,
               void(const VideoDescKey& key, GetDecodeStatsCB get_stats_cb));
  MOCK_METHOD1(DestroyStats, void(base::OnceClosure destroy_done_cb));
};

class MockDBProvider : public VideoDecodeStatsDBProvider {
 public:
  MockDBProvider() = default;
  ~MockDBProvider() override = default;

  MOCK_METHOD1(GetVideoDecodeStatsDB, void(GetCB get_db_b));
};

template <bool WithSeedDB>
class InMemoryDBTestBase : public testing::Test {
 public:
  InMemoryDBTestBase()
      : seed_db_(WithSeedDB ? new MockSeedDB() : nullptr),
        db_provider_(WithSeedDB ? new MockDBProvider() : nullptr),
        in_memory_db_(new InMemoryVideoDecodeStatsDBImpl(db_provider_.get())) {
    // Setup MockDBProvider to provide the seed DB. No need to initialize the
    // DB here since it too is a Mock.
    if (db_provider_) {
      using GetCB = VideoDecodeStatsDBProvider::GetCB;
      ON_CALL(*db_provider_, GetVideoDecodeStatsDB(_))
          .WillByDefault([&](GetCB cb) { std::move(cb).Run(seed_db_.get()); });
    }

    // The InMemoryDB should NEVER modify the seed DB.
    if (seed_db_) {
      EXPECT_CALL(*seed_db_, AppendDecodeStats(_, _, _)).Times(0);
      EXPECT_CALL(*seed_db_, DestroyStats(_)).Times(0);
    }
  }

  void InitializeEmptyDB() {
    if (seed_db_)
      EXPECT_CALL(*db_provider_, GetVideoDecodeStatsDB(_));

    EXPECT_CALL(*this, InitializeCB(true));

    in_memory_db_->Initialize(base::BindOnce(&InMemoryDBTestBase::InitializeCB,
                                             base::Unretained(this)));
    scoped_task_environment_.RunUntilIdle();
  }

  MOCK_METHOD1(InitializeCB, void(bool success));
  MOCK_METHOD1(AppendDecodeStatsCB, void(bool success));
  MOCK_METHOD2(
      GetDecodeStatsCB,
      void(bool success,
           std::unique_ptr<VideoDecodeStatsDB::DecodeStatsEntry> entry));
  MOCK_METHOD0(DestroyStatsCB, void());

 protected:
  using VideoDescKey = media::VideoDecodeStatsDB::VideoDescKey;
  using DecodeStatsEntry = media::VideoDecodeStatsDB::DecodeStatsEntry;

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  std::unique_ptr<MockSeedDB> seed_db_;
  std::unique_ptr<MockDBProvider> db_provider_;
  std::unique_ptr<InMemoryVideoDecodeStatsDBImpl> in_memory_db_;
};

// Specialization for tests that have/lack a seed DB. Some tests only make sense
// with seed DB, so we separate them.
class SeededInMemoryDBTest : public InMemoryDBTestBase<true> {};
class SeedlessInMemoryDBTest : public InMemoryDBTestBase<false> {};

TEST_F(SeedlessInMemoryDBTest, ReadExpectingEmpty) {
  InitializeEmptyDB();

  // Database is empty, seed DB is empty => expect empty stats entry.
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(kEmtpyEntry()))));

  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
}

TEST_F(SeededInMemoryDBTest, ReadExpectingEmpty) {
  InitializeEmptyDB();

  // Make seed DB return null (empty) for this request.
  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _))
      .WillOnce([](const auto& key, auto get_cb) {
        std::move(get_cb).Run(true, nullptr);
      });

  // Database is empty, seed DB is empty => expect empty stats entry.
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(kEmtpyEntry()))));

  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
}

TEST_F(SeededInMemoryDBTest, ReadExpectingSeedData) {
  InitializeEmptyDB();

  // Setup seed DB to return an entry for the test key.
  DecodeStatsEntry seed_entry(1000, 2, 10);

  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _))
      .WillOnce([&](const auto& key, auto get_cb) {
        std::move(get_cb).Run(true,
                              std::make_unique<DecodeStatsEntry>(seed_entry));
      });

  // Seed DB has a an entry for the test key. Expect it!
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(seed_entry))));

  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // Verify a second GetDecodeStats() call with the same key does not trigger a
  // second call to the seed DB (we cache it).
  EXPECT_CALL(*seed_db_, GetDecodeStats(_, _)).Times(0);
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(seed_entry))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
}

TEST_F(SeededInMemoryDBTest, AppendReadAndDestroy) {
  const DecodeStatsEntry seed_entry(1000, 2, 10);
  const DecodeStatsEntry double_seed_entry(2000, 4, 20);
  const DecodeStatsEntry triple_seed_entry(3000, 6, 30);

  InitializeEmptyDB();

  // Setup seed DB to always return an entry for the test key.
  ON_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _))
      .WillByDefault([&](const auto& key, auto get_cb) {
        std::move(get_cb).Run(true,
                              std::make_unique<DecodeStatsEntry>(seed_entry));
      });

  // First append should trigger a request for the same key from the seed DB.
  // Simulate a successful read providing seed_entry for that key.
  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _));

  // Append the same seed entry, doubling the stats for this key.
  EXPECT_CALL(*this, AppendDecodeStatsCB(true));
  in_memory_db_->AppendDecodeStats(
      kTestKey(), seed_entry,
      base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB,
                     base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // Seed DB should not be queried again for this key.
  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)).Times(0);

  // Now verify that the stats were doubled by the append above.
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(double_seed_entry))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // Append the same seed entry again to triple the stats. Additional appends
  // should not trigger queries the seed DB for this key.
  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)).Times(0);
  in_memory_db_->AppendDecodeStats(
      kTestKey(), seed_entry,
      base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB,
                     base::Unretained(this)));

  // Verify we have 3x the stats.
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(triple_seed_entry))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  // Now destroy the in-memory stats...
  EXPECT_CALL(*this, DestroyStatsCB());
  in_memory_db_->DestroyStats(base::BindOnce(
      &InMemoryDBTestBase::DestroyStatsCB, base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // With in-memory stats now gone, GetDecodeStats(kTestKey()) should again
  // trigger a call to the seed DB and return the un-doubled seed stats.
  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _));
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(seed_entry))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
}

TEST_F(SeedlessInMemoryDBTest, AppendReadAndDestroy) {
  const DecodeStatsEntry entry(50, 1, 5);
  const DecodeStatsEntry double_entry(100, 2, 10);

  InitializeEmptyDB();

  // Expect successful append to the empty seedless DB.
  EXPECT_CALL(*this, AppendDecodeStatsCB(true));
  in_memory_db_->AppendDecodeStats(
      kTestKey(), entry,
      base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB,
                     base::Unretained(this)));

  // Verify stats can be read back.
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(entry))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // Append same stats again to test summation.
  EXPECT_CALL(*this, AppendDecodeStatsCB(true));
  in_memory_db_->AppendDecodeStats(
      kTestKey(), entry,
      base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB,
                     base::Unretained(this)));

  // Verify doubled stats can be read back.
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(double_entry))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // Now destroy the in-memory stats...
  EXPECT_CALL(*this, DestroyStatsCB());
  in_memory_db_->DestroyStats(base::BindOnce(
      &InMemoryDBTestBase::DestroyStatsCB, base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // Verify DB now empty for this key.
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(kEmtpyEntry()))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
}

TEST_F(SeededInMemoryDBTest, ProvidedNullSeedDB) {
  // DB provider may provide a null seed DB if it encounters some error.
  EXPECT_CALL(*db_provider_, GetVideoDecodeStatsDB(_))
      .WillOnce([](auto get_db_cb) { std::move(get_db_cb).Run(nullptr); });

  // Failing to obtain the seed DB is not a show stopper. The in-memory DB
  // should simply carry on in a seedless fashion.
  EXPECT_CALL(*this, InitializeCB(true));
  in_memory_db_->Initialize(base::BindOnce(&InMemoryDBTestBase::InitializeCB,
                                           base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // Writes still succeed.
  EXPECT_CALL(*this, AppendDecodeStatsCB(true));
  const DecodeStatsEntry entry(50, 1, 5);
  in_memory_db_->AppendDecodeStats(
      kTestKey(), entry,
      base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB,
                     base::Unretained(this)));

  // Reads should still succeed.
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(entry))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
}

TEST_F(SeededInMemoryDBTest, SeedReadFailureOnGettingStats) {
  // Everything seems fine at initialization...
  InitializeEmptyDB();

  // But seed DB will repeatedly fail to provide stats.
  ON_CALL(*seed_db_, GetDecodeStats(_, _))
      .WillByDefault([](const auto& key, auto get_cb) {
        std::move(get_cb).Run(false, nullptr);
      });

  // Reading the in-memory will still try to read the seed DB, and the read
  // callback will simply report that the DB is empty for this key.
  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _));
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(kEmtpyEntry()))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
}

TEST_F(SeededInMemoryDBTest, SeedReadFailureOnAppendingingStats) {
  // Everything seems fine at initialization...
  InitializeEmptyDB();

  // But seed DB will repeatedly fail to provide stats.
  ON_CALL(*seed_db_, GetDecodeStats(_, _))
      .WillByDefault([](const auto& key, auto get_cb) {
        std::move(get_cb).Run(false, nullptr);
      });

  // Appending to the in-memory will still try to read the seed DB, and the
  // append will proceed successfully as if the seed DB were empty.
  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _));
  EXPECT_CALL(*this, AppendDecodeStatsCB(true));
  const DecodeStatsEntry entry(50, 1, 5);
  in_memory_db_->AppendDecodeStats(
      kTestKey(), entry,
      base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB,
                     base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
  ::testing::Mock::VerifyAndClear(this);

  // Reading the appended data works without issue and does not trigger new
  // queries to the seed DB.
  EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)).Times(0);
  EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(entry))));
  in_memory_db_->GetDecodeStats(
      kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB,
                                 base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();
}

}  // namespace media
