// Copyright 2015 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 "leaderd/webserver_client.h"

#include <vector>

#include <base/json/json_reader.h>
#include <base/logging.h>
#include <chromeos/http/http_request.h>
#include <chromeos/mime_utils.h>

using base::Value;
using chromeos::dbus_utils::AsyncEventSequencer;
using libwebserv::ProtocolHandler;
using libwebserv::Request;
using libwebserv::Response;

namespace leaderd {
namespace http_api {

const char kDiscoverGroupKey[] = "group";
const char kDiscoverLeaderKey[] = "leader";

const char kChallengeScoreKey[] = "score";
const char kChallengeGroupKey[] = "group";
const char kChallengeIdKey[] = "uuid";
const char kChallengeLeaderKey[] = "leader";

const char kAnnounceGroupKey[] = "group";
const char kAnnounceLeaderIdKey[] = "my_uuid";
const char kAnnounceScoreKey[] = "score";

}  // namespace http_api

WebServerClient::WebServerClient(Delegate* delegate,
                                 const std::string& web_handler_name)
    : delegate_(delegate),
      protocol_handler_name_{web_handler_name} {}

void WebServerClient::RegisterAsync(const scoped_refptr<dbus::Bus>& bus,
                                    const std::string& leaderd_service_name,
                                    AsyncEventSequencer* sequencer) {
  web_server_.OnProtocolHandlerConnected(
      base::Bind(&WebServerClient::OnProtocolHandlerConnected,
                 weak_ptr_factory_.GetWeakPtr()));
  web_server_.OnProtocolHandlerDisconnected(
      base::Bind(&WebServerClient::OnProtocolHandlerDisconnected,
                 weak_ptr_factory_.GetWeakPtr()));

  web_server_.Connect(
      bus, leaderd_service_name,
      sequencer->GetHandler("Server::Connect failed.", true),
      base::Bind(&base::DoNothing), base::Bind(&base::DoNothing));

  // Wanderers will try to discover the leader.
  web_server_.GetDefaultHttpHandler()->AddHandlerCallback(
      "/privet/v3/leadership/discover", chromeos::http::request_type::kPost,
      base::Bind(&WebServerClient::RequestHandler,
                 weak_ptr_factory_.GetWeakPtr(),
                 QueryType::DISCOVER));
  // Followers will try to challenge the leader.
  web_server_.GetDefaultHttpHandler()->AddHandlerCallback(
      "/privet/v3/leadership/challenge", chromeos::http::request_type::kPost,
      base::Bind(&WebServerClient::RequestHandler,
                 weak_ptr_factory_.GetWeakPtr(),
                 QueryType::CHALLENGE));
  // Leaders announce their presence.
  web_server_.GetDefaultHttpHandler()->AddHandlerCallback(
      "/privet/v3/leadership/announce", chromeos::http::request_type::kPost,
      base::Bind(&WebServerClient::RequestHandler,
                 weak_ptr_factory_.GetWeakPtr(),
                 QueryType::ANNOUNCE));
}

namespace {

std::unique_ptr<Value> GetBody(scoped_ptr<Request> request) {
  std::string data(request->GetData().begin(), request->GetData().end());
  VLOG(3) << "Input: " << data;

  std::unique_ptr<Value> value;

  if (!data.empty()) {
    std::string content_type = chromeos::mime::RemoveParameters(
        request->GetFirstHeader(chromeos::http::request_header::kContentType));
    if (content_type == chromeos::mime::application::kJson) {
      value.reset(base::JSONReader::Read(data));
    }
  }
  return value;
}

}  // namespace

void WebServerClient::RequestHandler(QueryType query_type,
                                     scoped_ptr<Request> request,
                                     scoped_ptr<Response> response) {
  std::unique_ptr<Value> value{GetBody(request.Pass())};
  const base::DictionaryValue* dictionary = nullptr;
  if (value) value->GetAsDictionary(&dictionary);
  std::unique_ptr<base::DictionaryValue> output;
  switch (query_type) {
    case QueryType::DISCOVER:
      output = ProcessDiscover(dictionary);
      break;
    case QueryType::CHALLENGE:
      output = ProcessChallenge(dictionary);
      break;
    case QueryType::ANNOUNCE:
      output = ProcessAnnouncement(dictionary);
      break;
  }
  if (output) {
    response->ReplyWithJson(chromeos::http::status_code::Ok, output.get());
  } else {
    response->ReplyWithError(chromeos::http::status_code::BadRequest,
                             std::string{});
  }
}

std::unique_ptr<base::DictionaryValue> WebServerClient::ProcessDiscover(
    const base::DictionaryValue* input_dictionary) {
  std::unique_ptr<base::DictionaryValue> output;
  std::string group;
  std::string leader_uuid;
  if (input_dictionary &&
      input_dictionary->GetString(http_api::kDiscoverGroupKey, &group) &&
      input_dictionary->size() == 1 &&
      delegate_->HandleLeaderDiscover(
          group, &leader_uuid)) {
    output.reset(new base::DictionaryValue());
    output->SetString(http_api::kDiscoverLeaderKey, leader_uuid);
  }
  return output;
}

std::unique_ptr<base::DictionaryValue> WebServerClient::ProcessChallenge(
    const base::DictionaryValue* input_dictionary) {
  std::unique_ptr<base::DictionaryValue> output;
  int score;
  std::string group;
  std::string uuid;
  std::string my_uuid;
  std::string leader_uuid;
  if (input_dictionary &&
      input_dictionary->GetInteger(http_api::kChallengeScoreKey, &score) &&
      input_dictionary->GetString(http_api::kChallengeGroupKey, &group) &&
      input_dictionary->GetString(http_api::kChallengeIdKey, &uuid) &&
      input_dictionary->size() == 3 &&
      delegate_->HandleLeaderChallenge(
          group, uuid, score, &leader_uuid, &my_uuid)) {
    output.reset(new base::DictionaryValue());
    output->SetString(http_api::kChallengeLeaderKey, leader_uuid);
    output->SetString(http_api::kChallengeIdKey, my_uuid);
  }
  return output;
}

std::unique_ptr<base::DictionaryValue> WebServerClient::ProcessAnnouncement(
    const base::DictionaryValue* input_dictionary) {
  std::unique_ptr<base::DictionaryValue> output;
  std::string group_id;
  std::string leader_id;
  int32_t score;
  if (input_dictionary &&
      input_dictionary->GetString(http_api::kAnnounceGroupKey, &group_id) &&
      input_dictionary->GetString(http_api::kAnnounceLeaderIdKey, &leader_id) &&
      input_dictionary->GetInteger(http_api::kAnnounceScoreKey, &score) &&
      input_dictionary->size() == 3 &&
      delegate_->HandleLeaderAnnouncement(
          group_id, leader_id, score)) {
    output.reset(new base::DictionaryValue());
  }
  return output;
}

void WebServerClient::OnProtocolHandlerConnected(
    ProtocolHandler* protocol_handler) {
  if (protocol_handler->GetName() == protocol_handler_name_)
    delegate_->SetWebServerPort(*protocol_handler->GetPorts().begin());
}

void WebServerClient::OnProtocolHandlerDisconnected(
    ProtocolHandler* protocol_handler) {
  if (protocol_handler->GetName() == protocol_handler_name_)
    delegate_->SetWebServerPort(0);
}

}  // namespace leaderd
