// 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/gtest_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_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(ClearStats, 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_, ClearStats(_)).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(ClearStatsCB, 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, AppendReadAndClear) {
  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, ClearStatsCB());
  in_memory_db_->ClearStats(base::BindOnce(&InMemoryDBTestBase::ClearStatsCB,
                                           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, AppendReadAndClear) {
  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, ClearStatsCB());
  in_memory_db_->ClearStats(base::BindOnce(&InMemoryDBTestBase::ClearStatsCB,
                                           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();
}

TEST_F(SeededInMemoryDBTest, SeedDBTearDownRace) {
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";

  // Establish depends-on connection from InMemoryDB to SeedDB.
  InitializeEmptyDB();

  // Clearing the seed-db dependency should trigger a crash.
  EXPECT_CHECK_DEATH(seed_db_.reset());
}

}  // namespace media
