// 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 <algorithm>
#include <iterator>
#include <set>
#include <string>

#include <base/check.h>
#include <base/files/file_path.h>
#include <base/notreached.h>
#include <brillo/errors/error.h>
#include <chromeos/dbus/service_constants.h>

#include "dlcservice/error.h"
#include "dlcservice/ref_count.h"
#include "dlcservice/system_state.h"
#include "dlcservice/utils.h"

using std::set;
using std::string;
using std::unique_ptr;

namespace dlcservice {

const char kRefCountFileName[] = "ref_count.bin";
const char kSessionStarted[] = "started";
const char kUsedByUser[] = "user";
const char kUsedBySystem[] = "system";

const int kDefaultExpirationDelayDays = 5;
const char kSystemUsername[] = "system";

// static
std::unique_ptr<RefCountInterface> RefCountInterface::Create(
    const string& used_by, const base::FilePath& prefs_path) {
  if (used_by == "user") {
    return std::make_unique<UserRefCount>(prefs_path);
  } else if (used_by == "system") {
    return std::make_unique<SystemRefCount>(prefs_path);
  } else {
    NOTREACHED() << "Invalid 'used_by' attribute in manifest: " << used_by;
  }
  return nullptr;
}

RefCountBase::RefCountBase(const base::FilePath& prefs_path) {
  last_access_time_us_ = 0;

  // Load the ref count proto only if it exists.
  ref_count_path_ = prefs_path.Append(kRefCountFileName);
  if (base::PathExists(ref_count_path_)) {
    RefCountInfo info;
    if (ReadRefCountInfo(ref_count_path_, &info)) {
      for (const auto& user : info.users()) {
        users_.insert(user.sanitized_username());
      }
      last_access_time_us_ = info.last_access_time_us();
    }
  }
}

// static
bool RefCountBase::ReadRefCountInfo(const base::FilePath& path,
                                    RefCountInfo* info) {
  DCHECK(info);
  string info_str;
  if (!base::ReadFileToString(path, &info_str)) {
    PLOG(ERROR) << "Failed to read the ref count proto file: " << path.value();
    return false;
  }
  if (!info->ParseFromString(info_str)) {
    LOG(ERROR) << "Failed to parse the ref count proto file: " << path.value();
    return false;
  }
  return true;
}

bool RefCountBase::InstalledDlc() {
  string username = GetCurrentUserName();
  if (username.empty()) {
    // Probably no user has logged in. So discard.
    return true;
  }

  // If we already have the user, ignore.
  if (users_.find(username) != users_.end())
    return true;

  // Add the current user to the list of users for this DLC.
  users_.insert(username);
  return Persist();
}

bool RefCountBase::UninstalledDlc() {
  string username = GetCurrentUserName();
  if (username.empty()) {
    // Probably no user has logged in. So discard.
    return true;
  }

  auto user_it = users_.find(username);
  // If we don't have this user, ignore.
  if (user_it == users_.end())
    return true;

  // Remove the user from the list of users currently using this DLC.
  users_.erase(user_it);
  return Persist();
}

bool RefCountBase::ShouldPurgeDlc() const {
  // If someone is using it, it should not be removed.
  if (users_.size() != 0) {
    return false;
  }

  // If the last access time has not been set, then we don't know the timeline
  // and this DLC should not be removed.
  if (last_access_time_us_ == 0) {
    return false;
  }

  base::Time last_accessed = base::Time::FromDeltaSinceWindowsEpoch(
      base::TimeDelta::FromMicroseconds(last_access_time_us_));
  base::TimeDelta delta_time =
      SystemState::Get()->clock()->Now() - last_accessed;
  return delta_time > GetExpirationDelay();
}

bool RefCountBase::Persist() {
  last_access_time_us_ = SystemState::Get()
                             ->clock()
                             ->Now()
                             .ToDeltaSinceWindowsEpoch()
                             .InMicroseconds();

  RefCountInfo info;
  info.set_last_access_time_us(last_access_time_us_);
  for (const auto& username : users_) {
    info.add_users()->set_sanitized_username(username);
  }

  string info_str;
  if (!info.SerializeToString(&info_str)) {
    LOG(ERROR) << "Failed to serialize user based ref count proto.";
    return false;
  }
  if (!WriteToFile(ref_count_path_, info_str)) {
    PLOG(ERROR) << "Failed to write user based ref count proto to: "
                << ref_count_path_;
    return false;
  }
  return true;
}

// UserRefCount implementations.
set<string> UserRefCount::device_users_;
unique_ptr<string> UserRefCount::primary_session_username_;

// static
void UserRefCount::SessionChanged(const string& state) {
  if (state == kSessionStarted) {
    device_users_ = ScanDirectory(SystemState::Get()->users_dir());
    SystemState::Get()->session_manager()->RetrievePrimarySessionAsync(
        base::Bind(&UserRefCount::OnSuccessRetrievePrimarySessionAsync),
        base::Bind(&UserRefCount::OnErrorRetrievePrimarySessionAsync));
  }
}

// static
void UserRefCount::OnSuccessRetrievePrimarySessionAsyncForTest(
    const std::string& username, const std::string& sanitized_username) {
  OnSuccessRetrievePrimarySessionAsync(username, sanitized_username);
}

// static
void UserRefCount::OnSuccessRetrievePrimarySessionAsync(
    const string& username, const string& sanitized_username) {
  primary_session_username_ = std::make_unique<string>(sanitized_username);
}

// static
void UserRefCount::OnErrorRetrievePrimarySessionAsync(brillo::Error* err) {
  LOG(ERROR) << "Failed to get the primary session's username with error: "
             << Error::ToString(err->Clone());
  primary_session_username_.reset();
}

UserRefCount::UserRefCount(const base::FilePath& prefs_path)
    : RefCountBase(prefs_path) {
  // We are only interested in users that exist on the system. Any other user
  // that don't exist in the system, but is included in the ref count should be
  // ignored. We don't necessarily need to delete these dangling users from the
  // proto file itself because one, that user might come back, and two it
  // doesn't really matter to the logic of ref counts because when we load, we
  // only care about the users we loaded and approved. On the next install or
  // uninstall the correct users will be persisted.
  set<string> intersection;
  std::set_intersection(users_.begin(), users_.end(), device_users_.begin(),
                        device_users_.end(),
                        std::inserter(intersection, intersection.end()));
  users_.swap(intersection);
}

}  // namespace dlcservice
