// 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 "buffet/webserv_client.h"

#include <memory>
#include <string>

#include <libwebserv/protocol_handler.h>
#include <libwebserv/request.h>
#include <libwebserv/response.h>
#include <libwebserv/server.h>

#include "buffet/dbus_constants.h"
#include "buffet/socket_stream.h"

namespace buffet {

namespace {

class RequestImpl : public weave::HttpServer::Request {
 public:
  explicit RequestImpl(std::unique_ptr<libwebserv::Request> request)
      : request_{std::move(request)} {}
  ~RequestImpl() override {}

  // HttpServer::Request implementation.
  const std::string& GetPath() const override { return request_->GetPath(); }
  std::string GetFirstHeader(const std::string& name) const override {
    return request_->GetFirstHeader(name);
  }

  // TODO(avakulenko): Remove this method and rewrite all call sites in libweave
  // to use GetDataStream() instead.
  const std::vector<uint8_t>& GetData() const override {
    if (request_data_)
      return *request_data_;

    request_data_.reset(new std::vector<uint8_t>);
    auto stream = request_->GetDataStream();
    if (stream) {
      if (stream->CanGetSize())
        request_data_->reserve(stream->GetRemainingSize());
      std::vector<uint8_t> buffer(16 * 1024);  // 16K seems to be good enough.
      size_t sz = 0;
      while (stream->ReadBlocking(buffer.data(), buffer.size(), &sz, nullptr) &&
             sz > 0) {
        request_data_->insert(request_data_->end(),
                              buffer.data(), buffer.data() + sz);
      }
    }
    return *request_data_;
  }

  std::unique_ptr<weave::Stream> GetDataStream() const override {
    auto stream = std::unique_ptr<weave::Stream>{
        new SocketStream{request_->GetDataStream()}};
    return stream;
  }

 private:
  std::unique_ptr<libwebserv::Request> request_;
  mutable std::unique_ptr<std::vector<uint8_t>> request_data_;

  DISALLOW_COPY_AND_ASSIGN(RequestImpl);
};

}  // namespace

WebServClient::~WebServClient() {
  web_server_->Disconnect();
}

void WebServClient::AddOnStateChangedCallback(
    const OnStateChangedCallback& callback) {
  on_state_changed_callbacks_.push_back(callback);
  callback.Run(*this);
}

void WebServClient::AddRequestHandler(const std::string& path_prefix,
                                      const OnRequestCallback& callback) {
  web_server_->GetDefaultHttpHandler()->AddHandlerCallback(
      path_prefix, "", base::Bind(&WebServClient::OnRequest,
                                  weak_ptr_factory_.GetWeakPtr(), callback));
  web_server_->GetDefaultHttpsHandler()->AddHandlerCallback(
      path_prefix, "", base::Bind(&WebServClient::OnRequest,
                                  weak_ptr_factory_.GetWeakPtr(), callback));
}

uint16_t WebServClient::GetHttpPort() const {
  return http_port_;
}

uint16_t WebServClient::GetHttpsPort() const {
  return https_port_;
}

const chromeos::Blob& WebServClient::GetHttpsCertificateFingerprint() const {
  return certificate_;
}

WebServClient::WebServClient(
    const scoped_refptr<dbus::Bus>& bus,
    chromeos::dbus_utils::AsyncEventSequencer* sequencer) {
  web_server_.reset(new libwebserv::Server);
  web_server_->OnProtocolHandlerConnected(
      base::Bind(&WebServClient::OnProtocolHandlerConnected,
                 weak_ptr_factory_.GetWeakPtr()));
  web_server_->OnProtocolHandlerDisconnected(
      base::Bind(&WebServClient::OnProtocolHandlerDisconnected,
                 weak_ptr_factory_.GetWeakPtr()));

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

void WebServClient::OnRequest(const OnRequestCallback& callback,
                              std::unique_ptr<libwebserv::Request> request,
                              std::unique_ptr<libwebserv::Response> response) {
  callback.Run(
      RequestImpl{std::move(request)},
      base::Bind(&WebServClient::OnResponse, weak_ptr_factory_.GetWeakPtr(),
                 base::Passed(&response)));
}

void WebServClient::OnResponse(std::unique_ptr<libwebserv::Response> response,
                               int status_code,
                               const std::string& data,
                               const std::string& mime_type) {
  response->ReplyWithText(status_code, data, mime_type);
}

void WebServClient::OnProtocolHandlerConnected(
    libwebserv::ProtocolHandler* protocol_handler) {
  if (protocol_handler->GetName() == libwebserv::ProtocolHandler::kHttp) {
    http_port_ = *protocol_handler->GetPorts().begin();
  } else if (protocol_handler->GetName() ==
             libwebserv::ProtocolHandler::kHttps) {
    https_port_ = *protocol_handler->GetPorts().begin();
    certificate_ = protocol_handler->GetCertificateFingerprint();
  }
  for (const auto& cb : on_state_changed_callbacks_)
    cb.Run(*this);
}

void WebServClient::OnProtocolHandlerDisconnected(
    libwebserv::ProtocolHandler* protocol_handler) {
  if (protocol_handler->GetName() == libwebserv::ProtocolHandler::kHttp) {
    http_port_ = 0;
  } else if (protocol_handler->GetName() ==
             libwebserv::ProtocolHandler::kHttps) {
    https_port_ = 0;
    certificate_.clear();
  }
  for (const auto& cb : on_state_changed_callbacks_)
    cb.Run(*this);
}

}  // namespace buffet
