// Copyright 2020 The Chromium OS 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 <string>
#include <vector>

#include <base/files/file_util.h>
#include <base/threading/platform_thread.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "dlcservice/ref_count.h"
#include "dlcservice/test_utils.h"
#include "dlcservice/utils.h"

using base::FilePath;
using std::string;
using std::vector;
using testing::_;
using testing::DoAll;
using testing::InvokeWithoutArgs;
using testing::Return;
using testing::SetArgPointee;

namespace dlcservice {

class RefCountTest : public BaseTest {
 public:
  RefCountTest() = default;

 protected:
  void SetUp() override {
    BaseTest::SetUp();
    ref_count_path_ = JoinPaths(prefs_path_, "ref_count.bin");
  }

  RefCountInfo ReadRefCountInfo() {
    RefCountInfo info;
    EXPECT_TRUE(RefCountBase::ReadRefCountInfo(ref_count_path_, &info));
    return info;
  }

  void GenerateRefCountInfo(const vector<string>& usernames,
                            int64_t access_time) {
    string str;
    RefCountInfo info;
    info.set_last_access_time_us(access_time);
    for (const auto& username : usernames) {
      info.add_users()->set_sanitized_username(username);
    }

    EXPECT_TRUE(info.SerializeToString(&str));
    EXPECT_TRUE(WriteToFile(ref_count_path_, str));
  }

  FilePath ref_count_path_;

 private:
  RefCountTest(const RefCountTest&) = delete;
  RefCountTest& operator=(const RefCountTest&) = delete;
};

TEST_F(RefCountTest, CreateUserBased) {
  auto manifest = GetDlcManifest(manifest_path_, kSecondDlc, kPackage);
  auto ref_count = RefCountInterface::Create(prefs_path_, manifest);
  RefCountInterface& ref_count_ref = *ref_count;
  EXPECT_EQ(typeid(ref_count_ref), typeid(UserRefCount));
}

TEST_F(RefCountTest, CreateSystem) {
  auto manifest = GetDlcManifest(manifest_path_, kFirstDlc, kPackage);
  auto ref_count = RefCountInterface::Create(prefs_path_, manifest);
  RefCountInterface& ref_count_ref = *ref_count;
  EXPECT_EQ(typeid(ref_count_ref), typeid(SystemRefCount));
}

// Make sure it can read from the file.
TEST_F(RefCountTest, Ctor) {
  auto manifest = GetDlcManifest(manifest_path_, kFirstDlc, kPackage);
  GenerateRefCountInfo({"user-1", "user-2"}, 10);
  SystemRefCount ref_count(prefs_path_, manifest);
  // TODO(ahassani): Improve the test so we don't access the private variables
  // like this.
  EXPECT_EQ(ref_count.users_.size(), 2);
  EXPECT_EQ(ref_count.last_access_time_us_, 10);
}

TEST_F(RefCountTest, SystemInstalledAndUninstallDlc) {
  auto manifest = GetDlcManifest(manifest_path_, kSecondDlc, kPackage);
  SystemRefCount ref_count(prefs_path_, manifest);
  EXPECT_TRUE(ref_count.InstalledDlc());
  auto info = ReadRefCountInfo();
  EXPECT_EQ(info.users(0).sanitized_username(), "system");

  EXPECT_TRUE(ref_count.UninstalledDlc());
  info = ReadRefCountInfo();
  EXPECT_EQ(info.users_size(), 0);
}

TEST_F(RefCountTest, UserInstalledAndUninstallDlc) {
  for (const auto& sanitized_username : {"user-1", "user-2"}) {
    auto path = JoinPaths(SystemState::Get()->users_dir(), sanitized_username);
    EXPECT_TRUE(base::CreateDirectoryAndGetError(path, nullptr));
  }

  EXPECT_CALL(*mock_session_manager_proxy_ptr_,
              RetrievePrimarySessionAsync(_, _, _))
      .WillOnce(InvokeWithoutArgs([]() {
        UserRefCount::OnSuccessRetrievePrimarySessionAsyncForTest("username-1",
                                                                  "user-1");
      }))
      .WillOnce(InvokeWithoutArgs([]() {
        UserRefCount::OnSuccessRetrievePrimarySessionAsyncForTest("username-2",
                                                                  "user-2");
      }));

  UserRefCount::SessionChanged(kSessionStarted);
  auto manifest = GetDlcManifest(manifest_path_, kSecondDlc, kPackage);
  UserRefCount ref_count(prefs_path_, manifest);
  EXPECT_TRUE(ref_count.InstalledDlc());
  auto info = ReadRefCountInfo();
  EXPECT_EQ(info.users_size(), 1);
  EXPECT_EQ(info.users(0).sanitized_username(), "user-1");

  UserRefCount::SessionChanged(kSessionStarted);
  EXPECT_TRUE(ref_count.InstalledDlc());
  info = ReadRefCountInfo();
  EXPECT_EQ(info.users_size(), 2);
  EXPECT_EQ(info.users(0).sanitized_username(), "user-1");
  EXPECT_EQ(info.users(1).sanitized_username(), "user-2");

  // Uninstall should remove the user now.
  EXPECT_TRUE(ref_count.UninstalledDlc());
  info = ReadRefCountInfo();
  EXPECT_EQ(info.users_size(), 1);
  EXPECT_EQ(info.users(0).sanitized_username(), "user-1");
}

TEST_F(RefCountTest, DeleteNotExistingUsers) {
  for (const auto& sanitized_username : {"user-1", "user-2"}) {
    auto path = JoinPaths(SystemState::Get()->users_dir(), sanitized_username);
    EXPECT_TRUE(base::CreateDirectoryAndGetError(path, nullptr));
  }

  EXPECT_CALL(*mock_session_manager_proxy_ptr_,
              RetrievePrimarySessionAsync(_, _, _))
      .WillOnce(InvokeWithoutArgs([]() {
        UserRefCount::OnSuccessRetrievePrimarySessionAsyncForTest("username-1",
                                                                  "user-1");
      }))
      .WillOnce(InvokeWithoutArgs([]() {
        UserRefCount::OnSuccessRetrievePrimarySessionAsyncForTest("username-2",
                                                                  "user-2");
      }))
      .WillOnce(InvokeWithoutArgs([]() {
        UserRefCount::OnSuccessRetrievePrimarySessionAsyncForTest("username-2",
                                                                  "user-2");
      }));

  // Install with both "user-1".
  auto manifest = GetDlcManifest(manifest_path_, kFirstDlc, kPackage);
  UserRefCount ref_count(prefs_path_, manifest);
  UserRefCount::SessionChanged(kSessionStarted);
  EXPECT_TRUE(ref_count.InstalledDlc());

  // Install with both "user-2".
  UserRefCount::SessionChanged(kSessionStarted);
  EXPECT_TRUE(ref_count.InstalledDlc());

  // Now delete one user of the system. Only remaining is "user-1".
  auto path = JoinPaths(SystemState::Get()->users_dir(), "user-1");
  EXPECT_TRUE(base::DeletePathRecursively(path));
  UserRefCount::SessionChanged(kSessionStarted);

  // Uninstall should remove both users after a reboot.
  UserRefCount ref_count2(prefs_path_, manifest);
  EXPECT_TRUE(ref_count2.UninstalledDlc());
  auto info = ReadRefCountInfo();
  EXPECT_EQ(info.users_size(), 0);
}

TEST_F(RefCountTest, ShouldPurgeDlcAfterInitialize) {
  auto manifest = GetDlcManifest(manifest_path_, kFirstDlc, kPackage);
  SystemRefCount ref_count(prefs_path_, manifest);

  // If the DLC is not touched yet, it should return false.
  EXPECT_FALSE(ref_count.ShouldPurgeDlc());
}

TEST_F(RefCountTest, ShouldPurgeDlcHasUser) {
  auto manifest = GetDlcManifest(manifest_path_, kFirstDlc, kPackage);
  SystemRefCount ref_count(prefs_path_, manifest);
  // After this ref count should be persisted.
  EXPECT_TRUE(ref_count.InstalledDlc());

  // We have a user using it, so we can't remove it.
  EXPECT_FALSE(ref_count.ShouldPurgeDlc());

  clock_.Advance(base::TimeDelta::FromDays(6));
  // Now the expiration is passed, but it should not be purged because it still
  // has a user.
  EXPECT_FALSE(ref_count.ShouldPurgeDlc());
}

TEST_F(RefCountTest, ShouldPurgeDlcExpirationDelay) {
  auto manifest = GetDlcManifest(manifest_path_, kFirstDlc, kPackage);
  SystemRefCount ref_count(prefs_path_, manifest);
  // Add a user.
  EXPECT_TRUE(ref_count.InstalledDlc());
  // Move the time a bit.
  clock_.Advance(base::TimeDelta::FromMinutes(6));
  // Now remove the user so we can test the expiration.
  EXPECT_TRUE(ref_count.UninstalledDlc());

  // We don't have a user, but expiration hasn't passed yet.
  EXPECT_FALSE(ref_count.ShouldPurgeDlc());

  clock_.Advance(base::TimeDelta::FromDays(6));
  // We have now reached the 5 days timeout. So with no user, it should be
  // removed.
  EXPECT_TRUE(ref_count.ShouldPurgeDlc());
}

}  // namespace dlcservice
