// Copyright 2018 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 "authpolicy/auth_data_cache.h"

#include <utility>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include "base/time/clock.h"
#include "base/time/default_clock.h"

#include "authpolicy/log_colors.h"

namespace authpolicy {
namespace {

constexpr char kLogHeader[] = "Auth Data Cache: ";

#define LOG_START(severity) \
  LOG_IF(severity, flags_->log_caches()) << kColorCaches << kLogHeader
#define PLOG_START(severity) \
  PLOG_IF(severity, flags_->log_caches()) << kColorCaches << kLogHeader
#define LOG_END kColorReset

// Size limit when loading the cached data file (256 kb).
constexpr size_t kCacheSizeLimit = 256 * 1024;

}  // namespace

AuthDataCache::AuthDataCache(const protos::DebugFlags* flags)
    : flags_(flags), clock_(std::make_unique<base::DefaultClock>()) {}

AuthDataCache::~AuthDataCache() = default;

bool AuthDataCache::Load(const base::FilePath& path) {
  data_.Clear();
  if (!enabled_)
    return true;

  if (!base::PathExists(path)) {
    LOG_START(ERROR) << "File '" << path.value() << "' does not exist"
                     << LOG_END;
    return false;
  }

  std::string data_blob;
  if (!base::ReadFileToStringWithMaxSize(path, &data_blob, kCacheSizeLimit)) {
    PLOG_START(ERROR) << "Failed to read '" << path.value() << "'" << LOG_END;
    return false;
  }

  if (!data_.ParseFromString(data_blob)) {
    LOG_START(ERROR) << "Failed to parse data from string" << LOG_END;
    return false;
  }

  LOG_START(INFO) << "Read '" << path.value() << "'" << LOG_END;
  return true;
}

bool AuthDataCache::Save(const base::FilePath& path) {
  if (!enabled_)
    return true;

  std::string data_blob;
  if (!data_.SerializeToString(&data_blob)) {
    LOG_START(ERROR) << "Failed to serialize data to string" << LOG_END;
    return false;
  }

  const int data_size = static_cast<int>(data_blob.size());
  if (base::WriteFile(path, data_blob.data(), data_size) != data_size) {
    LOG_START(ERROR) << "Failed to write '" << path.value() << "'" << LOG_END;
    return false;
  }

  // Lock access to authpolicyd rw.
  int mode =
      base::FILE_PERMISSION_READ_BY_USER | base::FILE_PERMISSION_WRITE_BY_USER;
  if (!base::SetPosixFilePermissions(path, mode)) {
    LOG_START(ERROR) << "Failed to set permissions on '" << path.value() << "'"
                     << LOG_END;
    return false;
  }

  LOG_START(INFO) << "Wrote '" << path.value() << "'" << LOG_END;
  return true;
}

void AuthDataCache::Clear() {
  data_.Clear();
}

base::Optional<std::string> AuthDataCache::GetWorkgroup(
    const std::string& realm) const {
  const protos::CachedRealmData* realm_data = GetRealmDataForRead(realm);
  if (!realm_data || !realm_data->has_workgroup()) {
    LOG_START(INFO) << "No workgroup cached" << LOG_END;
    return base::nullopt;
  }
  LOG_START(INFO) << "Using cached workgroup" << LOG_END;
  return realm_data->workgroup();
}

base::Optional<std::string> AuthDataCache::GetKdcIp(
    const std::string& realm) const {
  const protos::CachedRealmData* realm_data = GetRealmDataForRead(realm);
  if (!realm_data || !realm_data->has_kdc_ip()) {
    LOG_START(INFO) << "No KDC IP cached" << LOG_END;
    return base::nullopt;
  }
  LOG_START(INFO) << "Using cached KDC IP" << LOG_END;
  return realm_data->kdc_ip();
}

base::Optional<std::string> AuthDataCache::GetDcName(
    const std::string& realm) const {
  const protos::CachedRealmData* realm_data = GetRealmDataForRead(realm);
  if (!realm_data || !realm_data->has_dc_name()) {
    LOG_START(INFO) << "No DC name cached" << LOG_END;
    return base::nullopt;
  }
  LOG_START(INFO) << "Using cached DC name" << LOG_END;
  return realm_data->dc_name();
}

base::Optional<bool> AuthDataCache::GetIsAffiliated(
    const std::string& realm) const {
  const protos::CachedRealmData* realm_data = GetRealmDataForRead(realm);
  if (!realm_data || !realm_data->has_is_affiliated()) {
    LOG_START(INFO) << "No affiliation flag cached" << LOG_END;
    return base::nullopt;
  }
  LOG_START(INFO) << "Using cached affiliation flag" << LOG_END;
  return realm_data->is_affiliated();
}

void AuthDataCache::SetWorkgroup(const std::string& realm,
                                 const std::string& workgroup) {
  protos::CachedRealmData* realm_data = GetRealmDataForWrite(realm);
  if (realm_data) {
    LOG_START(INFO) << "Setting workgroup" << LOG_END;
    realm_data->set_workgroup(workgroup);
  }
}

void AuthDataCache::SetKdcIp(const std::string& realm,
                             const std::string& kdc_ip) {
  protos::CachedRealmData* realm_data = GetRealmDataForWrite(realm);
  if (realm_data) {
    LOG_START(INFO) << "Setting KDC IP" << LOG_END;
    realm_data->set_kdc_ip(kdc_ip);
  }
}

void AuthDataCache::SetDcName(const std::string& realm,
                              const std::string& dc_name) {
  protos::CachedRealmData* realm_data = GetRealmDataForWrite(realm);
  if (realm_data) {
    LOG_START(INFO) << "Setting DC name" << LOG_END;
    realm_data->set_dc_name(dc_name);
  }
}

void AuthDataCache::SetIsAffiliated(const std::string& realm,
                                    bool is_affiliated) {
  protos::CachedRealmData* realm_data = GetRealmDataForWrite(realm);
  if (realm_data) {
    realm_data->set_is_affiliated(is_affiliated);
    LOG_START(INFO) << "Setting affiliation flag" << LOG_END;
  }
}

void AuthDataCache::RemoveEntriesOlderThan(base::TimeDelta max_age) {
  base::Time now = clock_->Now();
  auto realm_data_map = data_.mutable_realm_data();
  for (auto it = realm_data_map->begin(); it != realm_data_map->end();
       /* empty */) {
    // Note: If the clock goes backwards for some reason, clear cache as well
    // just in case the clock was reset.
    protos::CachedRealmData& realm_data = it->second;
    base::TimeDelta age =
        now - base::Time::FromInternalValue(realm_data.cache_time());
    if (age < base::TimeDelta() || age >= max_age) {
      LOG_START(INFO) << "Removing entry from cache (age=" << age << ")"
                      << LOG_END;
      it = realm_data_map->erase(it);
    } else {
      ++it;
    }
  }
}

void AuthDataCache::SetClockForTesting(std::unique_ptr<base::Clock> clock) {
  clock_ = std::move(clock);
}

const protos::CachedRealmData* AuthDataCache::GetRealmDataForRead(
    const std::string& realm) const {
  if (!enabled_)
    return nullptr;
  auto it = data_.realm_data().find(realm);
  if (it == data_.realm_data().end())
    return nullptr;
  return &it->second;
}

protos::CachedRealmData* AuthDataCache::GetRealmDataForWrite(
    const std::string& realm) {
  if (!enabled_)
    return nullptr;
  protos::CachedRealmData* realm_data = &(*data_.mutable_realm_data())[realm];

  // Set cache time only on creation, but not on updates.
  if (!realm_data->has_cache_time())
    realm_data->set_cache_time(clock_->Now().ToInternalValue());

  return realm_data;
}

}  // namespace authpolicy
