// 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 "peerd/manager.h"

#include <base/format_macros.h>
#include <base/guid.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <brillo/dbus/async_event_sequencer.h>
#include <brillo/dbus/exported_object_manager.h>
#include <dbus/object_path.h>

#include "peerd/constants.h"
#include "peerd/dbus_constants.h"
#include "peerd/peer_manager_impl.h"
#include "peerd/published_peer.h"
#include "peerd/service.h"
#include "peerd/technologies.h"

using brillo::Any;
using brillo::Error;
using brillo::ErrorPtr;
using brillo::dbus_utils::AsyncEventSequencer;
using brillo::dbus_utils::DBusObject;
using brillo::dbus_utils::DBusParamReader;
using brillo::dbus_utils::DBusParamWriter;
using brillo::dbus_utils::DBusServiceWatcher;
using brillo::dbus_utils::ExportedObjectManager;
using dbus::ObjectPath;
using peerd::constants::kSerbusServiceId;
using peerd::dbus_constants::kPingResponse;
using peerd::dbus_constants::kSelfPath;
using std::map;
using std::set;
using std::string;
using std::unique_ptr;
using std::vector;

namespace peerd {
namespace errors {
namespace manager {

const char kAlreadyExposed[] = "manager.already_exposed";
const char kInvalidMonitoringOption[] = "manager.option";
const char kInvalidMonitoringTechnology[] = "manager.invalid_technology";
const char kInvalidMonitoringToken[] = "manager.monitoring_token";
const char kNotOwner[] = "manager.not_owner";
const char kUnknownServiceId[] = "manager.unknown_service_id";

}  // namespace manager
}  // namespace errors

Manager::Manager(ExportedObjectManager* object_manager,
                 const string& initial_mdns_prefix)
  : Manager(object_manager->GetBus(),
            unique_ptr<DBusObject>{new DBusObject{
                object_manager, object_manager->GetBus(),
                org::chromium::peerd::ManagerAdaptor::GetObjectPath()}},
            unique_ptr<PublishedPeer>{},
            unique_ptr<PeerManagerInterface>{},
            unique_ptr<AvahiClient>{},
            initial_mdns_prefix) {
}

Manager::Manager(scoped_refptr<dbus::Bus> bus,
                 unique_ptr<DBusObject> dbus_object,
                 unique_ptr<PublishedPeer> self,
                 unique_ptr<PeerManagerInterface> peer_manager,
                 unique_ptr<AvahiClient> avahi_client,
                 const string& initial_mdns_prefix)
    : bus_{bus},
      dbus_object_{std::move(dbus_object)},
      self_{std::move(self)},
      peer_manager_{std::move(peer_manager)},
      avahi_client_{std::move(avahi_client)} {
  // If we haven't gotten mocks for these objects, make real ones.
  if (!self_) {
    self_.reset(new PublishedPeer{
        bus_, dbus_object_->GetObjectManager().get(), ObjectPath{kSelfPath}});
  }
  if (!peer_manager_) {
    peer_manager_.reset(
        new PeerManagerImpl{bus_, dbus_object_->GetObjectManager().get()});
  }
  if (!avahi_client_) {
    avahi_client_.reset( new AvahiClient{bus_, peer_manager_.get()});
    avahi_client_->AttemptToUseMDnsPrefix(initial_mdns_prefix);
  }
}


void Manager::RegisterAsync(const CompletionAction& completion_callback) {
  scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
  dbus_adaptor_.RegisterWithDBusObject(dbus_object_.get());
  const bool self_success = self_->RegisterAsync(
      nullptr,
      base::GenerateGUID(),  // Every boot is a new GUID for now.
      base::Time::UnixEpoch(),
      sequencer->GetHandler("Failed exporting Self.", true));
  CHECK(self_success) << "Failed to RegisterAsync Self.";
  dbus_object_->RegisterAsync(
      sequencer->GetHandler("Failed exporting Manager.", true));
  avahi_client_->RegisterOnAvahiRestartCallback(
      base::Bind(&Manager::ShouldRefreshAvahiPublisher,
                 base::Unretained(this)));
  avahi_client_->RegisterAsync(
      sequencer->GetHandler("Failed AvahiClient.RegisterAsync().", true));
  sequencer->OnAllTasksCompletedCall({completion_callback});
}

bool Manager::StartMonitoring(
    ErrorPtr* error,
    const vector<string>& requested_technologies,
    const map<string, Any>& options,
    std::string* monitoring_token) {
  if (requested_technologies.empty()) {
    Error::AddTo(error,
                 FROM_HERE,
                 kPeerdErrorDomain,
                 errors::manager::kInvalidMonitoringTechnology,
                 "Expected at least one monitoring technology.");
    return false;
  }
  // We don't support any options right now.
  if (!options.empty()) {
    Error::AddTo(error,
                 FROM_HERE,
                 kPeerdErrorDomain,
                 errors::manager::kInvalidMonitoringOption,
                 "Did not expect any options to monitoring.");
    return false;
  }
  // Translate the technologies we're given to our internal bitmap
  // representation.
  technologies::TechnologySet combined;
  for (const auto& tech_text : requested_technologies) {
    if (!technologies::add_to(tech_text, &combined)) {
      Error::AddToPrintf(error,
                         FROM_HERE,
                         kPeerdErrorDomain,
                         errors::manager::kInvalidMonitoringTechnology,
                         "Invalid monitoring technology: %s.",
                         tech_text.c_str());
      return false;
    }
  }
  // Right now we don't support bluetooth technologies.
  if (combined.test(technologies::kBT) || combined.test(technologies::kBTLE)) {
      Error::AddTo(error,
                   FROM_HERE,
                   kPeerdErrorDomain,
                   errors::manager::kInvalidMonitoringTechnology,
                   "Unsupported monitoring technology.");
      return false;
  }
  *monitoring_token = "monitoring_" +
                      std::to_string(++monitoring_tokens_issued_);
  monitoring_requests_[*monitoring_token] = combined;
  UpdateMonitoredTechnologies();
  // TODO(wiley): Monitor DBus identifier for disconnect.
  return true;
}

bool Manager::StopMonitoring(brillo::ErrorPtr* error,
                             const string& monitoring_token) {
  auto it = monitoring_requests_.find(monitoring_token);
  if (it == monitoring_requests_.end()) {
    Error::AddToPrintf(error,
                       FROM_HERE,
                       kPeerdErrorDomain,
                       errors::manager::kInvalidMonitoringToken,
                       "Unknown monitoring token: %s.",
                       monitoring_token.c_str());
    return false;
  }
  monitoring_requests_.erase(it);
  UpdateMonitoredTechnologies();
  return true;
}


bool Manager::ExposeService(brillo::ErrorPtr* error,
                            dbus::Message* message,
                            const string& service_id,
                            const map<string, string>& service_info,
                            const map<string, Any>& options) {
  VLOG(1) << "Exposing service '" << service_id << "'.";
  if (service_id == kSerbusServiceId) {
    Error::AddToPrintf(error,
                       FROM_HERE,
                       kPeerdErrorDomain,
                       errors::service::kInvalidServiceId,
                       "Cannot expose a service named %s",
                       kSerbusServiceId);
    return false;
  }
  auto it = exposed_services_.find(service_id);
  if (it != exposed_services_.end()) {
    if (it->second->connection_name() != message->GetSender()) {
      Error::AddToPrintf(
          error, FROM_HERE, kPeerdErrorDomain, errors::manager::kAlreadyExposed,
          "Service %s was already exposed by another local process.",
          service_id.c_str());
      return false;
    }
    return self_->UpdateService(error, service_id, service_info, options);
  }
  if (!self_->AddPublishedService(error, service_id, service_info, options)) {
    return false;
  }
  // TODO(wiley) Maybe trigger an advertisement run since we have updated
  //             information.
  base::Closure on_connection_vanish = base::Bind(
      &Manager::OnDBusServiceDeath, base::Unretained(this), service_id);
  exposed_services_[service_id].reset(
      new DBusServiceWatcher{bus_, message->GetSender(), on_connection_vanish});
  return true;
}

bool Manager::RemoveExposedService(brillo::ErrorPtr* error,
                                   dbus::Message* message,
                                   const string& service_id) {
  auto it = exposed_services_.find(service_id);
  if (it == exposed_services_.end()) {
    Error::AddTo(error,
                 FROM_HERE,
                 kPeerdErrorDomain,
                 errors::manager::kUnknownServiceId,
                 "Unknown service id given to RemoveExposedService.");
    return false;
  }
  if (it->second->connection_name() != message->GetSender()) {
    Error::AddToPrintf(
        error, FROM_HERE, kPeerdErrorDomain, errors::manager::kNotOwner,
        "Service %s is owned by another local process.", service_id.c_str());
    return false;
  }
  bool success = self_->RemoveService(error, it->first);
  // Maybe RemoveService returned with an error, but either way, we should
  // forget this service.
  exposed_services_.erase(it);
  // TODO(wiley) Maybe trigger an advertisement run since we have updated
  //             information.
  return success;
}

string Manager::Ping() {
  return kPingResponse;
}

void Manager::ShouldRefreshAvahiPublisher() {
  LOG(INFO) << "Publishing services to mDNS";
  // The old publisher has been invalidated, and the records pulled.  We should
  // re-register the records we care about.
  self_->RegisterServicePublisher(
      avahi_client_->GetPublisher(self_->GetUUID()));
}

void Manager::UpdateMonitoredTechnologies() {
  technologies::TechnologySet combined;
  for (const auto& request : monitoring_requests_) {
    combined |= request.second;
  }
  dbus_adaptor_.SetMonitoredTechnologies(
      technologies::techs2strings(combined));
  if (combined.test(technologies::kMDNS)) {
    // Let the AvahiClient worry about if we're already monitoring.
    avahi_client_->StartMonitoring();
  } else {
    avahi_client_->StopMonitoring();
  }
}

void Manager::OnDBusServiceDeath(const std::string& service_id) {
  auto it = exposed_services_.find(service_id);
  if (it == exposed_services_.end()) { return; }
  self_->RemoveService(nullptr, it->first);
  exposed_services_.erase(it);
}

}  // namespace peerd
