// Copyright 2020 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/fuchsia/cdm/service/fuchsia_cdm_manager.h"

#include <fuchsia/media/drm/cpp/fidl.h>
#include <fuchsia/media/drm/cpp/fidl_test_base.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fpromise/promise.h>
#include <map>

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "media/fuchsia/cdm/service/mock_provision_fetcher.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace media {
namespace {

namespace drm = ::fuchsia::media::drm;

using ::testing::_;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::SaveArg;
using ::testing::WithArgs;
using MockProvisionFetcher = ::media::testing::MockProvisionFetcher;

std::unique_ptr<ProvisionFetcher> CreateMockProvisionFetcher() {
  auto mock_provision_fetcher = std::make_unique<MockProvisionFetcher>();
  ON_CALL(*mock_provision_fetcher, Retrieve(_, _, _))
      .WillByDefault(WithArgs<2>(
          Invoke([](ProvisionFetcher::ResponseCB response_callback) {
            std::move(response_callback).Run(true, "response");
          })));
  return mock_provision_fetcher;
}

class MockKeySystem : public drm::testing::KeySystem_TestBase {
 public:
  MockKeySystem() = default;
  ~MockKeySystem() override = default;

  drm::KeySystemHandle AddBinding() { return bindings_.AddBinding(this); }
  fidl::BindingSet<drm::KeySystem>& bindings() { return bindings_; }

  void NotImplemented_(const std::string& name) override { FAIL() << name; }

  MOCK_METHOD(void,
              AddDataStore,
              (uint32_t data_store_id,
               drm::DataStoreParams params,
               AddDataStoreCallback callback),
              (override));
  MOCK_METHOD(
      void,
      CreateContentDecryptionModule2,
      (uint32_t data_store_id,
       fidl::InterfaceRequest<drm::ContentDecryptionModule> cdm_request),
      (override));

 private:
  fidl::BindingSet<drm::KeySystem> bindings_;
};

class FuchsiaCdmManagerTest : public ::testing::Test {
 public:
  FuchsiaCdmManagerTest() { EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); }

  std::unique_ptr<FuchsiaCdmManager> CreateFuchsiaCdmManager(
      std::vector<base::StringPiece> key_systems,
      absl::optional<uint64_t> cdm_data_quota_bytes = absl::nullopt) {
    FuchsiaCdmManager::CreateKeySystemCallbackMap create_key_system_callbacks;

    for (const base::StringPiece& name : key_systems) {
      MockKeySystem& key_system = mock_key_systems_[name];
      create_key_system_callbacks.emplace(
          name, base::BindRepeating(&MockKeySystem::AddBinding,
                                    base::Unretained(&key_system)));
    }
    return std::make_unique<FuchsiaCdmManager>(
        std::move(create_key_system_callbacks), temp_dir_.GetPath(),
        cdm_data_quota_bytes);
  }

 protected:
  using MockKeySystemMap = std::map<base::StringPiece, MockKeySystem>;

  MockKeySystem& mock_key_system(const base::StringPiece& key_system_name) {
    return mock_key_systems_[key_system_name];
  }

  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::MainThreadType::IO};

  MockKeySystemMap mock_key_systems_;
  base::ScopedTempDir temp_dir_;
};

TEST_F(FuchsiaCdmManagerTest, NoKeySystems) {
  std::unique_ptr<FuchsiaCdmManager> cdm_manager = CreateFuchsiaCdmManager({});

  base::RunLoop run_loop;
  drm::ContentDecryptionModulePtr cdm_ptr;
  cdm_ptr.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_NOT_FOUND);
    run_loop.Quit();
  });

  cdm_manager->CreateAndProvision(
      "com.key_system", url::Origin(),
      base::BindRepeating(&CreateMockProvisionFetcher), cdm_ptr.NewRequest());
  run_loop.Run();
}

TEST_F(FuchsiaCdmManagerTest, CreateAndProvision) {
  constexpr char kKeySystem[] = "com.key_system.a";
  std::unique_ptr<FuchsiaCdmManager> cdm_manager =
      CreateFuchsiaCdmManager({kKeySystem});

  base::RunLoop run_loop;
  drm::ContentDecryptionModulePtr cdm_ptr;
  cdm_ptr.set_error_handler([&](zx_status_t status) { run_loop.Quit(); });

  uint32_t added_data_store_id = 0;
  uint32_t cdm_data_store_id = 0;
  EXPECT_CALL(mock_key_system(kKeySystem), AddDataStore(_, _, _))
      .WillOnce(WithArgs<0, 2>(
          Invoke([&](uint32_t data_store_id,
                     drm::KeySystem::AddDataStoreCallback callback) {
            added_data_store_id = data_store_id;
            callback(fpromise::ok());
          })));

  EXPECT_CALL(mock_key_system(kKeySystem), CreateContentDecryptionModule2(_, _))
      .WillOnce(SaveArg<0>(&cdm_data_store_id));

  cdm_manager->CreateAndProvision(
      kKeySystem, url::Origin(),
      base::BindRepeating(&CreateMockProvisionFetcher), cdm_ptr.NewRequest());
  run_loop.Run();

  EXPECT_NE(added_data_store_id, 0u);
  EXPECT_EQ(added_data_store_id, cdm_data_store_id);
}

TEST_F(FuchsiaCdmManagerTest, RecreateAfterDisconnect) {
  constexpr char kKeySystem[] = "com.key_system.a";
  std::unique_ptr<FuchsiaCdmManager> cdm_manager =
      CreateFuchsiaCdmManager({kKeySystem});

  uint32_t added_data_store_id = 0;
  EXPECT_CALL(mock_key_system(kKeySystem), AddDataStore(_, _, _))
      .WillOnce(WithArgs<0, 2>(
          Invoke([&](uint32_t data_store_id,
                     drm::KeySystem::AddDataStoreCallback callback) {
            added_data_store_id = data_store_id;
            callback(fpromise::ok());
          })));

  // Create a CDM to force a KeySystem binding
  base::RunLoop create_run_loop;
  drm::ContentDecryptionModulePtr cdm_ptr;
  cdm_ptr.set_error_handler(
      [&](zx_status_t status) { create_run_loop.Quit(); });
  cdm_manager->CreateAndProvision(
      kKeySystem, url::Origin(),
      base::BindRepeating(&CreateMockProvisionFetcher), cdm_ptr.NewRequest());
  create_run_loop.Run();
  ASSERT_EQ(mock_key_system(kKeySystem).bindings().size(), 1u);

  // Close the KeySystem's bindings and wait until empty
  base::RunLoop disconnect_run_loop;
  cdm_manager->set_on_key_system_disconnect_for_test_callback(
      base::BindLambdaForTesting([&](const std::string& key_system_name) {
        if (key_system_name == kKeySystem) {
          disconnect_run_loop.Quit();
        }
      }));
  mock_key_system(kKeySystem).bindings().CloseAll();
  disconnect_run_loop.Run();
  ASSERT_EQ(mock_key_system(kKeySystem).bindings().size(), 0u);

  EXPECT_CALL(mock_key_system(kKeySystem),
              AddDataStore(Eq(added_data_store_id), _, _))
      .WillOnce(
          WithArgs<2>(Invoke([](drm::KeySystem::AddDataStoreCallback callback) {
            callback(fpromise::ok());
          })));

  base::RunLoop recreate_run_loop;
  cdm_ptr.set_error_handler(
      [&](zx_status_t status) { recreate_run_loop.Quit(); });
  cdm_manager->CreateAndProvision(
      kKeySystem, url::Origin(),
      base::BindRepeating(&CreateMockProvisionFetcher), cdm_ptr.NewRequest());
  recreate_run_loop.Run();
  EXPECT_EQ(mock_key_system(kKeySystem).bindings().size(), 1u);
}

TEST_F(FuchsiaCdmManagerTest, SameOriginShareDataStore) {
  constexpr char kKeySystem[] = "com.key_system.a";
  std::unique_ptr<FuchsiaCdmManager> cdm_manager =
      CreateFuchsiaCdmManager({kKeySystem});

  base::RunLoop run_loop;
  drm::ContentDecryptionModulePtr cdm1, cdm2;
  auto error_handler = [&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
    if (!cdm1.is_bound() && !cdm2.is_bound()) {
      run_loop.Quit();
    }
  };
  cdm1.set_error_handler(error_handler);
  cdm2.set_error_handler(error_handler);

  EXPECT_CALL(mock_key_system(kKeySystem), AddDataStore(Eq(1u), _, _))
      .WillOnce(
          WithArgs<2>(Invoke([](drm::KeySystem::AddDataStoreCallback callback) {
            callback(fpromise::ok());
          })));
  EXPECT_CALL(mock_key_system(kKeySystem),
              CreateContentDecryptionModule2(Eq(1u), _))
      .Times(2);

  url::Origin origin = url::Origin::Create(GURL("http://origin_a.com"));
  cdm_manager->CreateAndProvision(
      kKeySystem, origin, base::BindRepeating(&CreateMockProvisionFetcher),
      cdm1.NewRequest());
  cdm_manager->CreateAndProvision(
      kKeySystem, origin, base::BindRepeating(&CreateMockProvisionFetcher),
      cdm2.NewRequest());

  run_loop.Run();
}

TEST_F(FuchsiaCdmManagerTest, DifferentOriginDoNotShareDataStore) {
  constexpr char kKeySystem[] = "com.key_system.a";
  std::unique_ptr<FuchsiaCdmManager> cdm_manager =
      CreateFuchsiaCdmManager({kKeySystem});

  base::RunLoop run_loop;
  drm::ContentDecryptionModulePtr cdm1, cdm2;
  auto error_handler = [&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
    if (!cdm1.is_bound() && !cdm2.is_bound()) {
      run_loop.Quit();
    }
  };
  cdm1.set_error_handler(error_handler);
  cdm2.set_error_handler(error_handler);

  EXPECT_CALL(mock_key_system(kKeySystem), AddDataStore(Eq(1u), _, _))
      .WillOnce(
          WithArgs<2>(Invoke([](drm::KeySystem::AddDataStoreCallback callback) {
            callback(fpromise::ok());
          })));
  EXPECT_CALL(mock_key_system(kKeySystem), AddDataStore(Eq(2u), _, _))
      .WillOnce(
          WithArgs<2>(Invoke([](drm::KeySystem::AddDataStoreCallback callback) {
            callback(fpromise::ok());
          })));
  EXPECT_CALL(mock_key_system(kKeySystem),
              CreateContentDecryptionModule2(Eq(1u), _))
      .Times(1);
  EXPECT_CALL(mock_key_system(kKeySystem),
              CreateContentDecryptionModule2(Eq(2u), _))
      .Times(1);

  url::Origin origin_a = url::Origin::Create(GURL("http://origin_a.com"));
  url::Origin origin_b = url::Origin::Create(GURL("http://origin_b.com"));
  cdm_manager->CreateAndProvision(
      kKeySystem, origin_a, base::BindRepeating(&CreateMockProvisionFetcher),
      cdm1.NewRequest());
  cdm_manager->CreateAndProvision(
      kKeySystem, origin_b, base::BindRepeating(&CreateMockProvisionFetcher),
      cdm2.NewRequest());

  run_loop.Run();
}

void CreateDummyCdmDirectory(const base::FilePath& cdm_data_path,
                             base::StringPiece origin,
                             base::StringPiece key_system,
                             uint64_t size) {
  const base::FilePath path = cdm_data_path.Append(origin).Append(key_system);
  CHECK(base::CreateDirectory(path));
  if (size) {
    std::vector<uint8_t> zeroes(size);
    CHECK(base::WriteFile(path.Append("zeroes"), zeroes));
  }
}

// Verify that the least recently used CDM data directories are removed, until
// the quota is met.  Also verify that old directories are removed regardless
// of whether they are empty or not.
TEST_F(FuchsiaCdmManagerTest, CdmDataQuotaBytes) {
  constexpr uint64_t kTestQuotaBytes = 1024;
  constexpr char kOriginDirectory1[] = "origin1";
  constexpr char kOriginDirectory2[] = "origin2";
  constexpr char kKeySystemDirectory1[] = "key_system1";
  constexpr char kKeySystemDirectory2[] = "key_system2";
  constexpr char kEmptyKeySystemDirectory[] = "empty_key_system";

  // Create fake CDM data directories for two origins, each with two key
  // systems, with each directory consuming 50% of the total quota, so that
  // two directories must be removed to meet quota.

  // Create least-recently-used directories & their contents.
  const base::FilePath temp_path = temp_dir_.GetPath();
  CreateDummyCdmDirectory(temp_path, kOriginDirectory1, kKeySystemDirectory1,
                          kTestQuotaBytes / 2);
  CreateDummyCdmDirectory(temp_path, kOriginDirectory2, kKeySystemDirectory2,
                          kTestQuotaBytes / 2);
  CreateDummyCdmDirectory(temp_path, kOriginDirectory1,
                          kEmptyKeySystemDirectory, 0);

  // Sleep to account for coarse-grained filesystem timestamps.
  base::PlatformThread::Sleep(base::Seconds(1));

  // Create the recently-used directories.
  CreateDummyCdmDirectory(temp_path, kOriginDirectory1, kKeySystemDirectory2,
                          kTestQuotaBytes / 2);
  CreateDummyCdmDirectory(temp_path, kOriginDirectory2, kKeySystemDirectory1,
                          kTestQuotaBytes / 2);
  CreateDummyCdmDirectory(temp_path, kOriginDirectory2,
                          kEmptyKeySystemDirectory, 0);

  // Create the CDM manager, to run the data directory quota enforcement.
  std::unique_ptr<FuchsiaCdmManager> cdm_manager =
      CreateFuchsiaCdmManager({}, kTestQuotaBytes);

  // Use a CreateAndProvision() request as a proxy to wait for quota enforcement
  // to finish being applied.
  base::RunLoop run_loop;
  drm::ContentDecryptionModulePtr cdm_ptr;
  cdm_ptr.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_NOT_FOUND);
    run_loop.Quit();
  });

  cdm_manager->CreateAndProvision(
      "com.key_system", url::Origin(),
      base::BindRepeating(&CreateMockProvisionFetcher), cdm_ptr.NewRequest());
  run_loop.Run();

  EXPECT_FALSE(base::PathExists(
      temp_path.Append(kOriginDirectory1).Append(kKeySystemDirectory1)));
  EXPECT_FALSE(base::PathExists(
      temp_path.Append(kOriginDirectory2).Append(kKeySystemDirectory2)));

  EXPECT_TRUE(base::PathExists(
      temp_path.Append(kOriginDirectory1).Append(kKeySystemDirectory2)));
  EXPECT_TRUE(base::PathExists(
      temp_path.Append(kOriginDirectory2).Append(kKeySystemDirectory1)));

  // Empty directories are currently always treated as old, causing them all to
  // be deleted if the CDM data directory exceeds its quota.
  EXPECT_FALSE(base::PathExists(
      temp_path.Append(kOriginDirectory1).Append(kEmptyKeySystemDirectory)));
  EXPECT_FALSE(base::PathExists(
      temp_path.Append(kOriginDirectory2).Append(kEmptyKeySystemDirectory)));
}

// Verify that if all key-system sub-directories for a given origin have been
// deleted then the origin's directory is also deleted.
TEST_F(FuchsiaCdmManagerTest, EmptyOriginDirectory) {
  constexpr uint64_t kTestQuotaBytes = 1024;
  constexpr char kInactiveOriginDirectory[] = "origin1";
  constexpr char kActiveOriginDirectory[] = "origin2";
  constexpr char kKeySystemDirectory1[] = "key_system1";
  constexpr char kKeySystemDirectory2[] = "key_system2";

  // Create dummy data for an inactive origin.
  const base::FilePath temp_path = temp_dir_.GetPath();
  CreateDummyCdmDirectory(temp_path, kInactiveOriginDirectory,
                          kKeySystemDirectory1, kTestQuotaBytes / 2);
  CreateDummyCdmDirectory(temp_path, kInactiveOriginDirectory,
                          kKeySystemDirectory2, kTestQuotaBytes / 2);

  // Sleep to account for coarse-grained filesystem timestamps.
  base::PlatformThread::Sleep(base::Seconds(1));

  // Create dummy data for a recently-used, active origin.
  CreateDummyCdmDirectory(temp_path, kActiveOriginDirectory,
                          kKeySystemDirectory2, kTestQuotaBytes);

  // Create the CDM manager, to run the data directory quota enforcement.
  std::unique_ptr<FuchsiaCdmManager> cdm_manager =
      CreateFuchsiaCdmManager({}, kTestQuotaBytes);

  // Use a CreateAndProvision() request as a proxy to wait for quota enforcement
  // to finish being applied.
  base::RunLoop run_loop;
  drm::ContentDecryptionModulePtr cdm_ptr;
  cdm_ptr.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_NOT_FOUND);
    run_loop.Quit();
  });

  cdm_manager->CreateAndProvision(
      "com.key_system", url::Origin(),
      base::BindRepeating(&CreateMockProvisionFetcher), cdm_ptr.NewRequest());
  run_loop.Run();

  EXPECT_FALSE(base::PathExists(temp_path.Append(kInactiveOriginDirectory)));
  EXPECT_TRUE(base::PathExists(
      temp_path.Append(kActiveOriginDirectory).Append(kKeySystemDirectory2)));
}

}  // namespace
}  // namespace media
