// 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 ref_count = RefCountInterface::Create(kUsedByUser, prefs_path_);
  RefCountInterface& ref_count_ref = *ref_count;
  EXPECT_EQ(typeid(ref_count_ref), typeid(UserRefCount));
}

TEST_F(RefCountTest, CreateSystem) {
  auto ref_count = RefCountInterface::Create(kUsedBySystem, prefs_path_);
  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) {
  GenerateRefCountInfo({"user-1", "user-2"}, 10);
  SystemRefCount ref_count(prefs_path_);
  // 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) {
  SystemRefCount ref_count(prefs_path_);
  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);
  UserRefCount ref_count(prefs_path_);
  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".
  UserRefCount ref_count(prefs_path_);
  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_);
  EXPECT_TRUE(ref_count2.UninstalledDlc());
  auto info = ReadRefCountInfo();
  EXPECT_EQ(info.users_size(), 0);
}

TEST_F(RefCountTest, ShouldPurgeDlcAfterInitialize) {
  SystemRefCount ref_count(prefs_path_);

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

TEST_F(RefCountTest, ShouldPurgeDlcHasUser) {
  SystemRefCount ref_count(prefs_path_);
  // 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) {
  SystemRefCount ref_count(prefs_path_);
  // 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
