// Copyright (c) 2012 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 "rlz/chromeos/lib/rlz_value_store_chromeos.h"

#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/files/important_file_writer.h"
#include "base/json/json_file_value_serializer.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "rlz/lib/lib_values.h"
#include "rlz/lib/recursive_cross_process_lock_posix.h"
#include "rlz/lib/rlz_lib.h"

namespace rlz_lib {

namespace {

// Key names.
const char kPingTimeKey[] = "ping_time";
const char kAccessPointKey[] = "access_points";
const char kProductEventKey[] = "product_events";
const char kStatefulEventKey[] = "stateful_events";

// Brand name used when there is no supplementary brand name.
const char kNoSupplementaryBrand[] = "_";

// RLZ store filename.
const base::FilePath::CharType kRLZDataFileName[] =
    FILE_PATH_LITERAL("RLZ Data");

// RLZ store lock filename
const base::FilePath::CharType kRLZLockFileName[] =
    FILE_PATH_LITERAL("RLZ Data.lock");

// RLZ store path for testing.
base::FilePath g_testing_rlz_store_path_;

// Returns file path of the RLZ storage.
base::FilePath GetRlzStorePath() {
  base::FilePath homedir;
  PathService::Get(base::DIR_HOME, &homedir);
  return g_testing_rlz_store_path_.empty() ?
      homedir.Append(kRLZDataFileName) :
      g_testing_rlz_store_path_.Append(kRLZDataFileName);
}

// Returns file path of the RLZ storage lock file.
base::FilePath GetRlzStoreLockPath() {
  base::FilePath homedir;
  PathService::Get(base::DIR_HOME, &homedir);
  return g_testing_rlz_store_path_.empty() ?
      homedir.Append(kRLZLockFileName) :
      g_testing_rlz_store_path_.Append(kRLZLockFileName);
}

// Returns the dictionary key for storing access point-related prefs.
std::string GetKeyName(const std::string& key, AccessPoint access_point) {
  std::string brand = SupplementaryBranding::GetBrand();
  if (brand.empty())
    brand = kNoSupplementaryBrand;
  return key + "." + GetAccessPointName(access_point) + "." + brand;
}

// Returns the dictionary key for storing product-related prefs.
std::string GetKeyName(const std::string& key, Product product) {
  std::string brand = SupplementaryBranding::GetBrand();
  if (brand.empty())
    brand = kNoSupplementaryBrand;
  return key + "." + GetProductName(product) + "." + brand;
}

}  // namespace

RlzValueStoreChromeOS::RlzValueStoreChromeOS(const base::FilePath& store_path)
    : rlz_store_(new base::DictionaryValue),
      store_path_(store_path),
      read_only_(true) {
  ReadStore();
}

RlzValueStoreChromeOS::~RlzValueStoreChromeOS() {
  WriteStore();
}

bool RlzValueStoreChromeOS::HasAccess(AccessType type) {
  DCHECK(CalledOnValidThread());
  return type == kReadAccess || !read_only_;
}

bool RlzValueStoreChromeOS::WritePingTime(Product product, int64_t time) {
  DCHECK(CalledOnValidThread());
  rlz_store_->SetString(GetKeyName(kPingTimeKey, product),
                        base::Int64ToString(time));
  return true;
}

bool RlzValueStoreChromeOS::ReadPingTime(Product product, int64_t* time) {
  DCHECK(CalledOnValidThread());
  std::string ping_time;
  return rlz_store_->GetString(GetKeyName(kPingTimeKey, product), &ping_time) &&
      base::StringToInt64(ping_time, time);
}

bool RlzValueStoreChromeOS::ClearPingTime(Product product) {
  DCHECK(CalledOnValidThread());
  rlz_store_->Remove(GetKeyName(kPingTimeKey, product), NULL);
  return true;
}

bool RlzValueStoreChromeOS::WriteAccessPointRlz(AccessPoint access_point,
                                                const char* new_rlz) {
  DCHECK(CalledOnValidThread());
  rlz_store_->SetString(
      GetKeyName(kAccessPointKey, access_point), new_rlz);
  return true;
}

bool RlzValueStoreChromeOS::ReadAccessPointRlz(AccessPoint access_point,
                                               char* rlz,
                                               size_t rlz_size) {
  DCHECK(CalledOnValidThread());
  std::string rlz_value;
  rlz_store_->GetString(GetKeyName(kAccessPointKey, access_point), &rlz_value);
  if (rlz_value.size() < rlz_size) {
    strncpy(rlz, rlz_value.c_str(), rlz_size);
    return true;
  }
  if (rlz_size > 0)
    *rlz = '\0';
  return false;
}

bool RlzValueStoreChromeOS::ClearAccessPointRlz(AccessPoint access_point) {
  DCHECK(CalledOnValidThread());
  rlz_store_->Remove(GetKeyName(kAccessPointKey, access_point), NULL);
  return true;
}

bool RlzValueStoreChromeOS::AddProductEvent(Product product,
                                            const char* event_rlz) {
  DCHECK(CalledOnValidThread());
  return AddValueToList(GetKeyName(kProductEventKey, product),
                        new base::StringValue(event_rlz));
}

bool RlzValueStoreChromeOS::ReadProductEvents(
    Product product,
    std::vector<std::string>* events) {
  DCHECK(CalledOnValidThread());
  base::ListValue* events_list = NULL; ;
  if (!rlz_store_->GetList(GetKeyName(kProductEventKey, product), &events_list))
    return false;
  events->clear();
  for (size_t i = 0; i < events_list->GetSize(); ++i) {
    std::string event;
    if (events_list->GetString(i, &event))
      events->push_back(event);
  }
  return true;
}

bool RlzValueStoreChromeOS::ClearProductEvent(Product product,
                                              const char* event_rlz) {
  DCHECK(CalledOnValidThread());
  base::StringValue event_value(event_rlz);
  return RemoveValueFromList(GetKeyName(kProductEventKey, product),
                             event_value);
}

bool RlzValueStoreChromeOS::ClearAllProductEvents(Product product) {
  DCHECK(CalledOnValidThread());
  rlz_store_->Remove(GetKeyName(kProductEventKey, product), NULL);
  return true;
}

bool RlzValueStoreChromeOS::AddStatefulEvent(Product product,
                                             const char* event_rlz) {
  DCHECK(CalledOnValidThread());
  return AddValueToList(GetKeyName(kStatefulEventKey, product),
                        new base::StringValue(event_rlz));
}

bool RlzValueStoreChromeOS::IsStatefulEvent(Product product,
                                            const char* event_rlz) {
  DCHECK(CalledOnValidThread());
  base::StringValue event_value(event_rlz);
  base::ListValue* events_list = NULL;
  return rlz_store_->GetList(GetKeyName(kStatefulEventKey, product),
                             &events_list) &&
      events_list->Find(event_value) != events_list->end();
}

bool RlzValueStoreChromeOS::ClearAllStatefulEvents(Product product) {
  DCHECK(CalledOnValidThread());
  rlz_store_->Remove(GetKeyName(kStatefulEventKey, product), NULL);
  return true;
}

void RlzValueStoreChromeOS::CollectGarbage() {
  DCHECK(CalledOnValidThread());
  NOTIMPLEMENTED();
}

void RlzValueStoreChromeOS::ReadStore() {
  int error_code = 0;
  std::string error_msg;
  JSONFileValueDeserializer deserializer(store_path_);
  std::unique_ptr<base::Value> value =
      deserializer.Deserialize(&error_code, &error_msg);
  switch (error_code) {
    case JSONFileValueDeserializer::JSON_NO_SUCH_FILE:
      read_only_ = false;
      break;
    case JSONFileValueDeserializer::JSON_NO_ERROR:
      read_only_ = false;
      rlz_store_.reset(static_cast<base::DictionaryValue*>(value.release()));
      break;
    default:
      LOG(ERROR) << "Error reading RLZ store: " << error_msg;
  }
}

void RlzValueStoreChromeOS::WriteStore() {
  std::string json_data;
  JSONStringValueSerializer serializer(&json_data);
  serializer.set_pretty_print(true);
  std::unique_ptr<base::DictionaryValue> copy =
      rlz_store_->DeepCopyWithoutEmptyChildren();
  if (!serializer.Serialize(*copy.get())) {
    LOG(ERROR) << "Failed to serialize RLZ data";
    NOTREACHED();
    return;
  }
  if (!base::ImportantFileWriter::WriteFileAtomically(store_path_, json_data))
    LOG(ERROR) << "Error writing RLZ store";
}

bool RlzValueStoreChromeOS::AddValueToList(const std::string& list_name,
                                           base::Value* value) {
  base::ListValue* list_value = NULL;
  if (!rlz_store_->GetList(list_name, &list_value)) {
    list_value = new base::ListValue;
    rlz_store_->Set(list_name, list_value);
  }
  list_value->AppendIfNotPresent(value);
  return true;
}

bool RlzValueStoreChromeOS::RemoveValueFromList(const std::string& list_name,
                                                const base::Value& value) {
  base::ListValue* list_value = NULL;
  if (!rlz_store_->GetList(list_name, &list_value))
    return false;
  size_t index;
  list_value->Remove(value, &index);
  return true;
}

namespace {

// RlzValueStoreChromeOS keeps its data in memory and only writes it to disk
// when ScopedRlzValueStoreLock goes out of scope. Hence, if several
// ScopedRlzValueStoreLocks are nested, they all need to use the same store
// object.

RecursiveCrossProcessLock g_recursive_lock =
    RECURSIVE_CROSS_PROCESS_LOCK_INITIALIZER;

// This counts the nesting depth of |ScopedRlzValueStoreLock|.
int g_lock_depth = 0;

// This is the shared store object. Non-|NULL| only when |g_lock_depth > 0|.
RlzValueStoreChromeOS* g_store = NULL;

}  // namespace

ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() {
  bool got_cross_process_lock =
      g_recursive_lock.TryGetCrossProcessLock(GetRlzStoreLockPath());
  // At this point, we hold the in-process lock, no matter the value of
  // |got_cross_process_lock|.

  ++g_lock_depth;
  if (!got_cross_process_lock) {
    // Acquiring cross-process lock failed, so simply return here.
    // In-process lock will be released in dtor.
    DCHECK(!g_store);
    return;
  }

  if (g_lock_depth > 1) {
    // Reuse the already existing store object.
    DCHECK(g_store);
    store_.reset(g_store);
    return;
  }

  // This is the topmost lock, create a new store object.
  DCHECK(!g_store);
  g_store = new RlzValueStoreChromeOS(GetRlzStorePath());
  store_.reset(g_store);
}

ScopedRlzValueStoreLock::~ScopedRlzValueStoreLock() {
  --g_lock_depth;
  DCHECK(g_lock_depth >= 0);

  if (g_lock_depth > 0) {
    // Other locks are still using store_, so don't free it yet.
    ignore_result(store_.release());
    return;
  }

  g_store = NULL;

  g_recursive_lock.ReleaseLock();
}

RlzValueStore* ScopedRlzValueStoreLock::GetStore() {
  return store_.get();
}

namespace testing {

void SetRlzStoreDirectory(const base::FilePath& directory) {
  g_testing_rlz_store_path_ = directory;
}

std::string RlzStoreFilenameStr() {
  return GetRlzStorePath().value();
}

}  // namespace testing

}  // namespace rlz_lib
