// Copyright 2014 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 "buffet/device_registration_info.h"

#include <memory>
#include <utility>
#include <vector>

#include <base/json/json_writer.h>
#include <base/values.h>

#include "buffet/data_encoding.h"
#include "buffet/device_registration_storage_keys.h"
#include "buffet/storage_impls.h"
#include "buffet/http_transport_curl.h"
#include "buffet/http_utils.h"
#include "buffet/mime_utils.h"
#include "buffet/string_utils.h"
#include "buffet/url_utils.h"

const char buffet::kErrorDomainOAuth2[] = "oauth2";
const char buffet::kErrorDomainGCD[] = "gcd";
const char buffet::kErrorDomainGCDServer[] = "gcd_server";
const char buffet::kErrorDomainBuffet[] = "buffet";

namespace buffet {
namespace storage_keys {

// Persistent keys
const char kClientId[]      = "client_id";
const char kClientSecret[]  = "client_secret";
const char kApiKey[]        = "api_key";
const char kRefreshToken[]  = "refresh_token";
const char kDeviceId[]      = "device_id";
const char kOAuthURL[]      = "oauth_url";
const char kServiceURL[]    = "service_url";
const char kRobotAccount[]  = "robot_account";
// Transient keys
const char kDeviceKind[]    = "device_kind";
const char kSystemName[]    = "system_name";
const char kDisplayName[]   = "display_name";

}  // namespace storage_keys
}  // namespace buffet

namespace {

const base::FilePath::CharType kDeviceInfoFilePath[] =
    FILE_PATH_LITERAL("/var/lib/buffet/device_reg_info");

bool GetParamValue(
    const std::map<std::string, std::shared_ptr<base::Value>>& params,
    const std::string& param_name,
    std::string* param_value) {
  auto p = params.find(param_name);
  if (p == params.end())
    return false;

  return p->second->GetAsString(param_value);
}

std::pair<std::string, std::string> BuildAuthHeader(
    const std::string& access_token_type,
    const std::string& access_token) {
  std::string authorization =
      buffet::string_utils::Join(' ', access_token_type, access_token);
  // Linter doesn't like the ; after } on the following line...
  return {buffet::http::request_header::kAuthorization,
          authorization};  // NOLINT
}

std::unique_ptr<base::DictionaryValue> ParseOAuthResponse(
    const buffet::http::Response* response, buffet::ErrorPtr* error) {
  int code = 0;
  auto resp = buffet::http::ParseJsonResponse(response, &code, error);
  if (resp && code >= buffet::http::status_code::BadRequest) {
    if (error) {
      std::string error_code, error_message;
      if (resp->GetString("error", &error_code) &&
          resp->GetString("error_description", &error_message)) {
        buffet::Error::AddTo(error, buffet::kErrorDomainOAuth2, error_code,
                             error_message);
      } else {
        buffet::Error::AddTo(error, buffet::kErrorDomainOAuth2,
                             "unexpected_response", "Unexpected OAuth error");
      }
    }
    return std::unique_ptr<base::DictionaryValue>();
  }
  return resp;
}

inline void SetUnexpectedError(buffet::ErrorPtr* error) {
  buffet::Error::AddTo(error, buffet::kErrorDomainGCD, "unexpected_response",
                       "Unexpected GCD error");
}

void ParseGCDError(const base::DictionaryValue* json, buffet::ErrorPtr* error) {
  if (!error)
    return;

  const base::Value* list_value = nullptr;
  const base::ListValue* error_list = nullptr;
  if (!json->Get("error.errors", &list_value) ||
      !list_value->GetAsList(&error_list)) {
    SetUnexpectedError(error);
    return;
  }

  for (size_t i = 0; i < error_list->GetSize(); i++) {
    const base::Value* error_value = nullptr;
    const base::DictionaryValue* error_object = nullptr;
    if (!error_list->Get(i, &error_value) ||
        !error_value->GetAsDictionary(&error_object)) {
      SetUnexpectedError(error);
      continue;
    }
    std::string error_code, error_message;
    if (error_object->GetString("reason", &error_code) &&
        error_object->GetString("message", &error_message)) {
      buffet::Error::AddTo(error, buffet::kErrorDomainGCDServer,
                           error_code, error_message);
    } else {
      SetUnexpectedError(error);
    }
  }
}

std::string BuildURL(const std::string& url,
                     const std::vector<std::string>& subpaths,
                     const buffet::data_encoding::WebParamList& params) {
  std::string result = buffet::url::CombineMultiple(url, subpaths);
  return buffet::url::AppendQueryParams(result, params);
}

}  // anonymous namespace

namespace buffet {

DeviceRegistrationInfo::DeviceRegistrationInfo()
    : transport_(new http::curl::Transport()),
      // TODO(avakulenko): Figure out security implications of storing
      // this data unencrypted.
      storage_(new FileStorage(base::FilePath(kDeviceInfoFilePath))) {
}

DeviceRegistrationInfo::DeviceRegistrationInfo(
    std::shared_ptr<http::Transport> transport,
    std::shared_ptr<StorageInterface> storage) : transport_(transport),
                                                 storage_(storage) {
}

std::pair<std::string, std::string>
    DeviceRegistrationInfo::GetAuthorizationHeader() const {
  return BuildAuthHeader("Bearer", access_token_);
}

std::string DeviceRegistrationInfo::GetServiceURL(
    const std::string& subpath,
    const data_encoding::WebParamList& params) const {
  return BuildURL(service_url_, {subpath}, params);
}

std::string DeviceRegistrationInfo::GetDeviceURL(
    const std::string& subpath,
    const data_encoding::WebParamList& params) const {
  CHECK(!device_id_.empty()) << "Must have a valid device ID";
  return BuildURL(service_url_, {"devices", device_id_, subpath}, params);
}

std::string DeviceRegistrationInfo::GetOAuthURL(
    const std::string& subpath,
    const data_encoding::WebParamList& params) const {
  return BuildURL(oauth_url_, {subpath}, params);
}

std::string DeviceRegistrationInfo::GetDeviceId(ErrorPtr* error) {
  return CheckRegistration(error) ? device_id_ : std::string();
}

bool DeviceRegistrationInfo::Load() {
  auto value = storage_->Load();
  const base::DictionaryValue* dict = nullptr;
  if (!value || !value->GetAsDictionary(&dict))
    return false;

  // Get the values into temp variables first to make sure we can get
  // all the data correctly before changing the state of this object.
  std::string client_id;
  if (!dict->GetString(storage_keys::kClientId, &client_id))
    return false;
  std::string client_secret;
  if (!dict->GetString(storage_keys::kClientSecret, &client_secret))
    return false;
  std::string api_key;
  if (!dict->GetString(storage_keys::kApiKey, &api_key))
    return false;
  std::string refresh_token;
  if (!dict->GetString(storage_keys::kRefreshToken, &refresh_token))
    return false;
  std::string device_id;
  if (!dict->GetString(storage_keys::kDeviceId, &device_id))
    return false;
  std::string oauth_url;
  if (!dict->GetString(storage_keys::kOAuthURL, &oauth_url))
    return false;
  std::string service_url;
  if (!dict->GetString(storage_keys::kServiceURL, &service_url))
    return false;
  std::string device_robot_account;
  if (!dict->GetString(storage_keys::kRobotAccount, &device_robot_account))
    return false;

  client_id_            = client_id;
  client_secret_        = client_secret;
  api_key_              = api_key;
  refresh_token_        = refresh_token;
  device_id_            = device_id;
  oauth_url_            = oauth_url;
  service_url_          = service_url;
  device_robot_account_ = device_robot_account;
  return true;
}

bool DeviceRegistrationInfo::Save() const {
  base::DictionaryValue dict;
  dict.SetString(storage_keys::kClientId,     client_id_);
  dict.SetString(storage_keys::kClientSecret, client_secret_);
  dict.SetString(storage_keys::kApiKey,       api_key_);
  dict.SetString(storage_keys::kRefreshToken, refresh_token_);
  dict.SetString(storage_keys::kDeviceId,     device_id_);
  dict.SetString(storage_keys::kOAuthURL,     oauth_url_);
  dict.SetString(storage_keys::kServiceURL,   service_url_);
  dict.SetString(storage_keys::kRobotAccount, device_robot_account_);
  return storage_->Save(&dict);
}

bool DeviceRegistrationInfo::CheckRegistration(ErrorPtr* error) {
  LOG(INFO) << "Checking device registration record.";
  if (refresh_token_.empty() ||
      device_id_.empty() ||
      device_robot_account_.empty()) {
    LOG(INFO) << "No valid device registration record found.";
    Error::AddTo(error, kErrorDomainGCD, "device_not_registered",
                 "No valid device registration record found");
    return false;
  }

  LOG(INFO) << "Device registration record found.";
  return ValidateAndRefreshAccessToken(error);
}

bool DeviceRegistrationInfo::ValidateAndRefreshAccessToken(ErrorPtr* error) {
  LOG(INFO) << "Checking access token expiration.";
  if (!access_token_.empty() &&
      !access_token_expiration_.is_null() &&
      access_token_expiration_ > base::Time::Now()) {
    LOG(INFO) << "Access token is still valid.";
    return true;
  }

  auto response = http::PostFormData(GetOAuthURL("token"), {
    {"refresh_token", refresh_token_},
    {"client_id", client_id_},
    {"client_secret", client_secret_},
    {"grant_type", "refresh_token"},
  }, transport_, error);
  if (!response)
    return false;

  auto json = ParseOAuthResponse(response.get(), error);
  if (!json)
    return false;

  int expires_in = 0;
  if (!json->GetString("access_token", &access_token_) ||
      !json->GetInteger("expires_in", &expires_in) ||
      access_token_.empty() ||
      expires_in <= 0) {
    LOG(ERROR) << "Access token unavailable.";
    Error::AddTo(error, kErrorDomainOAuth2, "unexpected_server_response",
                 "Access token unavailable");
    return false;
  }

  access_token_expiration_ = base::Time::Now() +
                             base::TimeDelta::FromSeconds(expires_in);

  LOG(INFO) << "Access token is refreshed for additional " << expires_in
            << " seconds.";
  return true;
}

std::unique_ptr<base::Value> DeviceRegistrationInfo::GetDeviceInfo(
    ErrorPtr* error) {
  if (!CheckRegistration(error))
    return std::unique_ptr<base::Value>();

  auto response = http::Get(GetDeviceURL(),
                            {GetAuthorizationHeader()}, transport_, error);
  int status_code = 0;
  std::unique_ptr<base::DictionaryValue> json =
      http::ParseJsonResponse(response.get(), &status_code, error);
  if (json) {
    if (status_code >= http::status_code::BadRequest) {
      LOG(WARNING) << "Failed to retrieve the device info. Response code = "
                   << status_code;
      ParseGCDError(json.get(), error);
      return std::unique_ptr<base::Value>();
    }
  }
  return std::unique_ptr<base::Value>(json.release());
}

bool CheckParam(const std::string& param_name,
                const std::string& param_value,
                ErrorPtr* error) {
  if (!param_value.empty())
    return true;

  Error::AddTo(error, kErrorDomainBuffet, "missing_parameter",
               "Parameter " + param_name + " not specified");
  return false;
}

std::string DeviceRegistrationInfo::StartRegistration(
    const std::map<std::string, std::shared_ptr<base::Value>>& params,
    ErrorPtr* error) {
  GetParamValue(params, storage_keys::kClientId, &client_id_);
  GetParamValue(params, storage_keys::kClientSecret, &client_secret_);
  GetParamValue(params, storage_keys::kApiKey, &api_key_);
  GetParamValue(params, storage_keys::kDeviceId, &device_id_);
  GetParamValue(params, storage_keys::kDeviceKind, &device_kind_);
  GetParamValue(params, storage_keys::kSystemName, &system_name_);
  GetParamValue(params, storage_keys::kDisplayName, &display_name_);
  GetParamValue(params, storage_keys::kOAuthURL, &oauth_url_);
  GetParamValue(params, storage_keys::kServiceURL, &service_url_);

  if (!CheckParam(storage_keys::kClientId, client_id_, error))
    return std::string();
  if (!CheckParam(storage_keys::kClientSecret, client_secret_, error))
    return std::string();
  if (!CheckParam(storage_keys::kApiKey, api_key_, error))
    return std::string();
  if (!CheckParam(storage_keys::kDeviceKind, device_kind_, error))
    return std::string();
  if (!CheckParam(storage_keys::kSystemName, system_name_, error))
    return std::string();
  if (!CheckParam(storage_keys::kOAuthURL, oauth_url_, error))
    return std::string();
  if (!CheckParam(storage_keys::kServiceURL, service_url_, error))
    return std::string();

  std::vector<std::pair<std::string, std::vector<std::string>>> commands = {
    {"SetDeviceConfiguration", {"data"}}
  };

  base::DictionaryValue req_json;
  base::ListValue* set_device_configuration_params = new base::ListValue;
  base::DictionaryValue* param1 = new base::DictionaryValue;
  param1->SetString("name", "data");
  set_device_configuration_params->Append(param1);

  base::ListValue* vendor_commands = new base::ListValue;
  for (auto&& pair : commands) {
    base::ListValue* params = new base::ListValue;
    for (auto&& param_name : pair.second) {
      base::DictionaryValue* param = new base::DictionaryValue;
      param->SetString("name", param_name);
      params->Append(param);
    }
    base::DictionaryValue* command = new base::DictionaryValue;
    command->SetString("name", pair.first);
    command->Set("parameter", params);
    vendor_commands->Append(command);
  }

  req_json.SetString("oauthClientId", client_id_);
  req_json.SetString("deviceDraft.deviceKind", device_kind_);
  req_json.SetString("deviceDraft.systemName", system_name_);
  req_json.SetString("deviceDraft.displayName", display_name_);
  req_json.SetString("deviceDraft.channel.supportedType", "xmpp");
  req_json.Set("deviceDraft.commands.base.vendorCommands", vendor_commands);

  std::string url = GetServiceURL("registrationTickets", {{"key", api_key_}});
  auto resp_json = http::ParseJsonResponse(
      http::PostJson(url, &req_json, transport_, error).get(), nullptr, error);
  if (!resp_json)
    return std::string();

  if (!resp_json->GetString("id", &ticket_id_)) {
    Error::AddTo(error, kErrorDomainGCD, "unexpected_response",
                 "Device ID missing");
    return std::string();
  }

  std::string auth_url = GetOAuthURL("auth", {
    {"scope", "https://www.googleapis.com/auth/clouddevices"},
    {"redirect_uri", "urn:ietf:wg:oauth:2.0:oob"},
    {"response_type", "code"},
    {"client_id", client_id_}
  });

  base::DictionaryValue json;
  json.SetString("ticket_id", ticket_id_);
  json.SetString("auth_url", auth_url);

  std::string ret;
  base::JSONWriter::Write(&json, &ret);
  return ret;
}

bool DeviceRegistrationInfo::FinishRegistration(
    const std::string& user_auth_code, ErrorPtr* error) {
  if (ticket_id_.empty()) {
    LOG(ERROR) << "Finish registration without ticket ID";
    Error::AddTo(error, kErrorDomainBuffet, "registration_not_started",
                 "Device registration not started");
    return false;
  }

  std::string url = GetServiceURL("registrationTickets/" + ticket_id_);
  std::unique_ptr<http::Response> response;
  if (!user_auth_code.empty()) {
    response = http::PostFormData(GetOAuthURL("token"), {
      {"code", user_auth_code},
      {"client_id", client_id_},
      {"client_secret", client_secret_},
      {"redirect_uri", "urn:ietf:wg:oauth:2.0:oob"},
      {"grant_type", "authorization_code"}
    }, transport_, error);
    if (!response)
      return false;

    auto json_resp = ParseOAuthResponse(response.get(), error);
    if (!json_resp)
      return false;

    std::string user_access_token;
    std::string token_type;
    if (!json_resp->GetString("access_token", &user_access_token) ||
        !json_resp->GetString("token_type", &token_type)) {
      Error::AddTo(error, kErrorDomainOAuth2, "unexpected_response",
                   "User access_token is missing in response");
      return false;
    }

    base::DictionaryValue user_info;
    user_info.SetString("userEmail", "me");
    response = http::PatchJson(
        url, &user_info, {BuildAuthHeader(token_type, user_access_token)},
        transport_, error);

    auto json = http::ParseJsonResponse(response.get(), nullptr, error);
    if (!json)
      return false;
  }

  std::string auth_code;
  url += "/finalize?key=" + api_key_;
  LOG(INFO) << "Sending request to: " << url;
  response = http::PostBinary(url, nullptr, 0, transport_, error);
  if (!response)
    return false;
  auto json_resp = http::ParseJsonResponse(response.get(), nullptr, error);
  if (!json_resp)
    return false;
  if (!response->IsSuccessful()) {
    ParseGCDError(json_resp.get(), error);
    return false;
  }
  if (!json_resp->GetString("robotAccountEmail", &device_robot_account_) ||
      !json_resp->GetString("robotAccountAuthorizationCode", &auth_code) ||
      !json_resp->GetString("deviceDraft.id", &device_id_)) {
    Error::AddTo(error, kErrorDomainGCD, "unexpected_response",
                 "Device account missing in response");
    return false;
  }

  // Now get access_token and refresh_token
  response = http::PostFormData(GetOAuthURL("token"), {
    {"code", auth_code},
    {"client_id", client_id_},
    {"client_secret", client_secret_},
    {"redirect_uri", "oob"},
    {"scope", "https://www.googleapis.com/auth/clouddevices"},
    {"grant_type", "authorization_code"}
  }, transport_, error);
  if (!response)
    return false;

  json_resp = ParseOAuthResponse(response.get(), error);
  int expires_in = 0;
  if (!json_resp ||
      !json_resp->GetString("access_token", &access_token_) ||
      !json_resp->GetString("refresh_token", &refresh_token_) ||
      !json_resp->GetInteger("expires_in", &expires_in) ||
      access_token_.empty() ||
      refresh_token_.empty() ||
      expires_in <= 0) {
    Error::AddTo(error, kErrorDomainGCD, "unexpected_response",
                  "Device access_token missing in response");
    return false;
  }

  access_token_expiration_ = base::Time::Now() +
                             base::TimeDelta::FromSeconds(expires_in);

  Save();
  return true;
}

}  // namespace buffet
