// 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 "chrome/browser/extensions/api/storage/storage_api.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/storage/settings_frontend.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/storage.h"
#include "content/public/browser/browser_thread.h"

namespace extensions {

using content::BrowserThread;

// SettingsFunction

SettingsFunction::SettingsFunction()
    : settings_namespace_(settings_namespace::INVALID) {}

SettingsFunction::~SettingsFunction() {}

bool SettingsFunction::ShouldSkipQuotaLimiting() const {
  // Only apply quota if this is for sync storage.
  std::string settings_namespace_string;
  if (!args_->GetString(0, &settings_namespace_string)) {
    // This should be EXTENSION_FUNCTION_VALIDATE(false) but there is no way
    // to signify that from this function. It will be caught in RunImpl().
    return false;
  }
  return settings_namespace_string != "sync";
}

bool SettingsFunction::RunImpl() {
  std::string settings_namespace_string;
  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &settings_namespace_string));
  args_->Remove(0, NULL);
  settings_namespace_ =
      settings_namespace::FromString(settings_namespace_string);
  EXTENSION_FUNCTION_VALIDATE(
      settings_namespace_ != settings_namespace::INVALID);

  SettingsFrontend* frontend =
      profile()->GetExtensionService()->settings_frontend();
  if (!frontend->IsStorageEnabled(settings_namespace_)) {
    error_ = base::StringPrintf(
        "\"%s\" is not available in this instance of Chrome",
        settings_namespace_string.c_str());
    return false;
  }

  observers_ = frontend->GetObservers();
  frontend->RunWithStorage(
      extension_id(),
      settings_namespace_,
      base::Bind(&SettingsFunction::AsyncRunWithStorage, this));
  return true;
}

void SettingsFunction::AsyncRunWithStorage(ValueStore* storage) {
  bool success = RunWithStorage(storage);
  BrowserThread::PostTask(
      BrowserThread::UI,
      FROM_HERE,
      base::Bind(&SettingsFunction::SendResponse, this, success));
}

bool SettingsFunction::UseReadResult(ValueStore::ReadResult read_result) {
  if (read_result->HasError()) {
    error_ = read_result->error().message;
    return false;
  }

  base::DictionaryValue* result = new base::DictionaryValue();
  result->Swap(&read_result->settings());
  SetResult(result);
  return true;
}

bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result) {
  if (result->HasError()) {
    error_ = result->error().message;
    return false;
  }

  if (!result->changes().empty()) {
    observers_->Notify(
        &SettingsObserver::OnSettingsChanged,
        extension_id(),
        settings_namespace_,
        ValueStoreChange::ToJson(result->changes()));
  }

  return true;
}

// Concrete settings functions

namespace {

// Adds all StringValues from a ListValue to a vector of strings.
void AddAllStringValues(const base::ListValue& from,
                        std::vector<std::string>* to) {
  DCHECK(to->empty());
  std::string as_string;
  for (base::ListValue::const_iterator it = from.begin();
       it != from.end(); ++it) {
    if ((*it)->GetAsString(&as_string)) {
      to->push_back(as_string);
    }
  }
}

// Gets the keys of a DictionaryValue.
std::vector<std::string> GetKeys(const base::DictionaryValue& dict) {
  std::vector<std::string> keys;
  for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
    keys.push_back(it.key());
  }
  return keys;
}

// Creates quota heuristics for settings modification.
void GetModificationQuotaLimitHeuristics(QuotaLimitHeuristics* heuristics) {
  QuotaLimitHeuristic::Config longLimitConfig = {
    // See storage.json for current value.
    api::storage::sync::MAX_WRITE_OPERATIONS_PER_HOUR,
    base::TimeDelta::FromHours(1)
  };
  heuristics->push_back(
      new ExtensionsQuotaService::TimedLimit(
          longLimitConfig,
          new QuotaLimitHeuristic::SingletonBucketMapper(),
          "MAX_WRITE_OPERATIONS_PER_HOUR"));

  // A max of 10 operations per minute, sustained over 10 minutes.
  QuotaLimitHeuristic::Config shortLimitConfig = {
    // See storage.json for current value.
    api::storage::sync::MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE,
    base::TimeDelta::FromMinutes(1)
  };
  heuristics->push_back(
      new ExtensionsQuotaService::SustainedLimit(
          base::TimeDelta::FromMinutes(10),
          shortLimitConfig,
          new QuotaLimitHeuristic::SingletonBucketMapper(),
          "MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE"));
};

}  // namespace

bool StorageStorageAreaGetFunction::RunWithStorage(ValueStore* storage) {
  base::Value* input = NULL;
  EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));

  switch (input->GetType()) {
    case base::Value::TYPE_NULL:
      return UseReadResult(storage->Get());

    case base::Value::TYPE_STRING: {
      std::string as_string;
      input->GetAsString(&as_string);
      return UseReadResult(storage->Get(as_string));
    }

    case base::Value::TYPE_LIST: {
      std::vector<std::string> as_string_list;
      AddAllStringValues(*static_cast<base::ListValue*>(input),
                         &as_string_list);
      return UseReadResult(storage->Get(as_string_list));
    }

    case base::Value::TYPE_DICTIONARY: {
      base::DictionaryValue* as_dict = static_cast<base::DictionaryValue*>(input);
      ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict));
      if (result->HasError()) {
        return UseReadResult(result.Pass());
      }

      base::DictionaryValue* with_default_values = as_dict->DeepCopy();
      with_default_values->MergeDictionary(&result->settings());
      return UseReadResult(
          ValueStore::MakeReadResult(make_scoped_ptr(with_default_values)));
    }

    default:
      EXTENSION_FUNCTION_VALIDATE(false);
      return false;
  }
}

bool StorageStorageAreaGetBytesInUseFunction::RunWithStorage(
    ValueStore* storage) {
  base::Value* input = NULL;
  EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));

  size_t bytes_in_use = 0;

  switch (input->GetType()) {
    case base::Value::TYPE_NULL:
      bytes_in_use = storage->GetBytesInUse();
      break;

    case base::Value::TYPE_STRING: {
      std::string as_string;
      input->GetAsString(&as_string);
      bytes_in_use = storage->GetBytesInUse(as_string);
      break;
    }

    case base::Value::TYPE_LIST: {
      std::vector<std::string> as_string_list;
      AddAllStringValues(*static_cast<base::ListValue*>(input),
                         &as_string_list);
      bytes_in_use = storage->GetBytesInUse(as_string_list);
      break;
    }

    default:
      EXTENSION_FUNCTION_VALIDATE(false);
      return false;
  }

  SetResult(new base::FundamentalValue(static_cast<int>(bytes_in_use)));
  return true;
}

bool StorageStorageAreaSetFunction::RunWithStorage(ValueStore* storage) {
  base::DictionaryValue* input = NULL;
  EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input));
  return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input));
}

void StorageStorageAreaSetFunction::GetQuotaLimitHeuristics(
    QuotaLimitHeuristics* heuristics) const {
  GetModificationQuotaLimitHeuristics(heuristics);
}

bool StorageStorageAreaRemoveFunction::RunWithStorage(ValueStore* storage) {
  base::Value* input = NULL;
  EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));

  switch (input->GetType()) {
    case base::Value::TYPE_STRING: {
      std::string as_string;
      input->GetAsString(&as_string);
      return UseWriteResult(storage->Remove(as_string));
    }

    case base::Value::TYPE_LIST: {
      std::vector<std::string> as_string_list;
      AddAllStringValues(*static_cast<base::ListValue*>(input),
                         &as_string_list);
      return UseWriteResult(storage->Remove(as_string_list));
    }

    default:
      EXTENSION_FUNCTION_VALIDATE(false);
      return false;
  };
}

void StorageStorageAreaRemoveFunction::GetQuotaLimitHeuristics(
    QuotaLimitHeuristics* heuristics) const {
  GetModificationQuotaLimitHeuristics(heuristics);
}

bool StorageStorageAreaClearFunction::RunWithStorage(ValueStore* storage) {
  return UseWriteResult(storage->Clear());
}

void StorageStorageAreaClearFunction::GetQuotaLimitHeuristics(
    QuotaLimitHeuristics* heuristics) const {
  GetModificationQuotaLimitHeuristics(heuristics);
}

}  // namespace extensions
