// 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 <memory>
#include <string>
#include <sysexits.h>

#include <base/bind.h>
#include <base/command_line.h>
#include <base/json/json_reader.h>
#include <base/memory/weak_ptr.h>
#include <base/strings/string_number_conversions.h>
#include <base/values.h>
#include <chromeos/daemons/dbus_daemon.h>
#include <chromeos/flag_helper.h>
#include <chromeos/http/http_request.h>
#include <chromeos/key_value_store.h>
#include <chromeos/mime_utils.h>
#include <chromeos/strings/string_utils.h>
#include <chromeos/syslog_logging.h>
#include <libwebserv/protocol_handler.h>
#include <libwebserv/request.h>
#include <libwebserv/response.h>
#include <libwebserv/server.h>

#include "privetd/ap_manager_client.h"
#include "privetd/cloud_delegate.h"
#include "privetd/constants.h"
#include "privetd/daemon_state.h"
#include "privetd/dbus_manager.h"
#include "privetd/device_delegate.h"
#include "privetd/peerd_client.h"
#include "privetd/privet_handler.h"
#include "privetd/privetd_conf_parser.h"
#include "privetd/security_manager.h"
#include "privetd/shill_client.h"
#include "privetd/wifi_bootstrap_manager.h"

namespace privetd {

namespace {

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

const char kDefaultConfigFilePath[] = "/etc/privetd/config";
const char kDefaultStateFilePath[] = "/var/lib/privetd/privetd.state";

std::string GetFirstHeader(const Request& request, const std::string& name) {
  std::vector<std::string> headers = request.GetHeader(name);
  return headers.empty() ? std::string() : headers.front();
}

const char kServiceName[] = "org.chromium.privetd";
const char kRootPath[] = "/org/chromium/privetd";

class Daemon : public chromeos::DBusServiceDaemon {
 public:
  Daemon(bool disable_security,
         bool enable_ping,
         const std::vector<std::string>& device_whitelist,
         const base::FilePath& config_path,
         const base::FilePath& state_path)
      : DBusServiceDaemon(kServiceName, kRootPath),
        disable_security_(disable_security),
        enable_ping_(enable_ping),
        device_whitelist_(device_whitelist),
        config_path_(config_path),
        state_store_(new DaemonState(state_path)) {}

  void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
    chromeos::KeyValueStore config_store;
    if (!config_store.Load(config_path_)) {
      LOG(ERROR) << "Failed to read privetd config file from "
                 << config_path_.value();
    } else {
      CHECK(parser_.Parse(config_store))
          << "Failed to read configuration file.";
    }
    state_store_->Init();
    device_ = DeviceDelegate::CreateDefault(
        &parser_, state_store_.get(),
        base::Bind(&Daemon::OnChanged, base::Unretained(this)));
    if (parser_.gcd_bootstrap_mode() != GcdBootstrapMode::kDisabled) {
      cloud_ = CloudDelegate::CreateDefault(
          bus_, device_.get(),
          base::Bind(&Daemon::OnChanged, base::Unretained(this)));
    }
    security_.reset(
        new SecurityManager(parser_.embedded_code(), disable_security_));
    shill_client_.reset(new ShillClient(bus_, device_whitelist_));
    shill_client_->RegisterConnectivityListener(
        base::Bind(&Daemon::OnConnectivityChanged, base::Unretained(this)));
    ap_manager_client_.reset(new ApManagerClient(bus_));

    if (parser_.wifi_bootstrap_mode() != WiFiBootstrapMode::kDisabled) {
      VLOG(1) << "Enabling WiFi bootstrapping.";
      wifi_bootstrap_manager_.reset(new WifiBootstrapManager(
          state_store_.get(), shill_client_.get(), ap_manager_client_.get(),
          device_.get(), cloud_.get(), parser_.connect_timeout_seconds(),
          parser_.bootstrap_timeout_seconds(),
          parser_.monitor_timeout_seconds()));
      wifi_bootstrap_manager_->Init();
    }

    privet_handler_.reset(new PrivetHandler(cloud_.get(), device_.get(),
                                            security_.get(),
                                            wifi_bootstrap_manager_.get()));

    peerd_client_.reset(new PeerdClient(bus_, device_.get(), cloud_.get(),
                                        wifi_bootstrap_manager_.get()));

    web_server_.OnProtocolHandlerConnected(
        base::Bind(&Daemon::OnProtocolHandlerConnected,
                   weak_ptr_factory_.GetWeakPtr()));
    web_server_.OnProtocolHandlerDisconnected(
        base::Bind(&Daemon::OnProtocolHandlerDisconnected,
                   weak_ptr_factory_.GetWeakPtr()));

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

    web_server_.GetDefaultHttpHandler()->AddHandlerCallback(
        "/privet/", "",
        base::Bind(&Daemon::PrivetRequestHandler, base::Unretained(this)));
    web_server_.GetDefaultHttpsHandler()->AddHandlerCallback(
        "/privet/", "",
        base::Bind(&Daemon::PrivetRequestHandler, base::Unretained(this)));
    if (enable_ping_) {
      web_server_.GetDefaultHttpHandler()->AddHandlerCallback(
          "/privet/ping", chromeos::http::request_type::kGet,
          base::Bind(&Daemon::HelloWorldHandler, base::Unretained(this)));
      web_server_.GetDefaultHttpsHandler()->AddHandlerCallback(
          "/privet/ping", chromeos::http::request_type::kGet,
          base::Bind(&Daemon::HelloWorldHandler, base::Unretained(this)));
    }

    dbus_manager_.reset(new DBusManager{object_manager_.get(),
                                        wifi_bootstrap_manager_.get(),
                                        cloud_.get(),
                                        security_.get()});
    dbus_manager_->RegisterAsync(
        sequencer->GetHandler("DBusManager.RegisterAsync() failed.", true));
  }

  void OnShutdown(int* return_code) override {
    web_server_.Disconnect();
    DBusDaemon::OnShutdown(return_code);
  }

 private:
  void PrivetRequestHandler(scoped_ptr<Request> request,
                            scoped_ptr<Response> response) {
    std::string auth_header = GetFirstHeader(
        *request, chromeos::http::request_header::kAuthorization);
    if (auth_header.empty() && disable_security_)
      auth_header = "Privet anonymous";
    std::string data(request->GetData().begin(), request->GetData().end());
    VLOG(3) << "Input: " << data;

    base::DictionaryValue empty;
    std::unique_ptr<base::Value> value;
    const base::DictionaryValue* dictionary = nullptr;

    if (data.empty()) {
      dictionary = &empty;
    } else {
      std::string content_type =
          chromeos::mime::RemoveParameters(GetFirstHeader(
              *request, chromeos::http::request_header::kContentType));
      if (content_type == chromeos::mime::application::kJson) {
        value.reset(base::JSONReader::Read(data));
        if (value)
          value->GetAsDictionary(&dictionary);
      }
    }

    privet_handler_->HandleRequest(
        request->GetPath(), auth_header, dictionary,
        base::Bind(&Daemon::PrivetResponseHandler, base::Unretained(this),
                   base::Passed(&response)));
  }

  void PrivetResponseHandler(scoped_ptr<Response> response,
                             int status,
                             const base::DictionaryValue& output) {
    VLOG(3) << "status: " << status << ", Output: " << output;
    if (status == chromeos::http::status_code::NotFound)
      response->ReplyWithErrorNotFound();
    else
      response->ReplyWithJson(status, &output);
  }

  void HelloWorldHandler(scoped_ptr<Request> request,
                         scoped_ptr<Response> response) {
    response->ReplyWithText(chromeos::http::status_code::Ok, "Hello, world!",
                            chromeos::mime::text::kPlain);
  }

  void OnChanged() {
    if (peerd_client_)
      peerd_client_->Update();
  }

  void OnConnectivityChanged(bool online) {
    OnChanged();
  }

  void OnProtocolHandlerConnected(ProtocolHandler* protocol_handler) {
    if (protocol_handler->GetID() == ProtocolHandler::kHttp) {
      device_->SetHttpPort(protocol_handler->GetPort());
      if (peerd_client_)
        peerd_client_->Update();
    } else if (protocol_handler->GetID() == ProtocolHandler::kHttps) {
      device_->SetHttpsPort(protocol_handler->GetPort());
      security_->SetCertificateFingerprint(
          protocol_handler->GetCertificateFingerprint());
    }
  }

  void OnProtocolHandlerDisconnected(ProtocolHandler* protocol_handler) {
    if (protocol_handler->GetID() == ProtocolHandler::kHttp) {
      device_->SetHttpPort(0);
      if (peerd_client_)
        peerd_client_->Update();
    } else if (protocol_handler->GetID() == ProtocolHandler::kHttps) {
      device_->SetHttpsPort(0);
      security_->SetCertificateFingerprint({});
    }
  }

  bool disable_security_;
  bool enable_ping_;
  PrivetdConfigParser parser_;
  std::vector<std::string> device_whitelist_;
  base::FilePath config_path_;
  std::unique_ptr<DaemonState> state_store_;
  std::unique_ptr<CloudDelegate> cloud_;
  std::unique_ptr<DeviceDelegate> device_;
  std::unique_ptr<SecurityManager> security_;
  std::unique_ptr<ShillClient> shill_client_;
  std::unique_ptr<ApManagerClient> ap_manager_client_;
  std::unique_ptr<WifiBootstrapManager> wifi_bootstrap_manager_;
  std::unique_ptr<PrivetHandler> privet_handler_;
  std::unique_ptr<PeerdClient> peerd_client_;
  std::unique_ptr<DBusManager> dbus_manager_;
  libwebserv::Server web_server_;

  base::WeakPtrFactory<Daemon> weak_ptr_factory_{this};
  DISALLOW_COPY_AND_ASSIGN(Daemon);
};

}  // anonymous namespace

}  // namespace privetd

int main(int argc, char* argv[]) {
  DEFINE_bool(disable_security, false, "disable Privet security for tests");
  DEFINE_bool(enable_ping, false, "enable test HTTP handler at /privet/ping");
  DEFINE_bool(log_to_stderr, false, "log trace messages to stderr as well");
  DEFINE_string(config_path, privetd::kDefaultConfigFilePath,
                "Path to file containing config information.");
  DEFINE_string(state_path, privetd::kDefaultStateFilePath,
                "Path to file containing state information.");
  DEFINE_string(device_whitelist, "",
                "Comma separated list of network interfaces to monitor for "
                "connectivity (an empty list enables all interfaces).");

  chromeos::FlagHelper::Init(argc, argv, "Privet protocol handler daemon");

  int flags = chromeos::kLogToSyslog;
  if (FLAGS_log_to_stderr)
    flags |= chromeos::kLogToStderr;
  chromeos::InitLog(flags | chromeos::kLogHeader);

  if (FLAGS_config_path.empty())
    FLAGS_config_path = privetd::kDefaultConfigFilePath;

  if (FLAGS_state_path.empty())
    FLAGS_state_path = privetd::kDefaultStateFilePath;

  auto device_whitelist =
      chromeos::string_utils::Split(FLAGS_device_whitelist, ',', true, true);

  privetd::Daemon daemon(FLAGS_disable_security, FLAGS_enable_ping,
                         device_whitelist, base::FilePath(FLAGS_config_path),
                         base::FilePath(FLAGS_state_path));
  return daemon.Run();
}
