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

#include <base/format_macros.h>
#include <base/guid.h>
#include <base/memory/weak_ptr.h>
#include <base/strings/string_util.h>
#include <chromeos/dbus/exported_object_manager.h>

#include "peerd/dbus_constants.h"
#include "peerd/typedefs.h"

using base::Time;
using base::TimeDelta;
using chromeos::Any;
using chromeos::Error;
using chromeos::dbus_utils::AsyncEventSequencer;
using chromeos::dbus_utils::DBusObject;
using chromeos::dbus_utils::ExportedObjectManager;
using dbus::ObjectPath;
using peerd::dbus_constants::kServicePathFragment;
using std::map;
using std::string;
using std::vector;
using std::unique_ptr;

namespace peerd {

namespace errors {
namespace peer {

const char kInvalidUUID[] = "peer.uuid";
const char kInvalidTime[] = "peer.time";
const char kUnknownService[] = "peer.unknown_service";
const char kDuplicateServiceID[] = "peer.duplicate_service_id";

}  // namespace peer
}  // namespace errors

Peer::Peer(const scoped_refptr<dbus::Bus>& bus,
           ExportedObjectManager* object_manager,
           const ObjectPath& path)
    : bus_(bus),
      dbus_object_(new DBusObject{object_manager, bus, path}),
      service_path_prefix_(path.value() + kServicePathFragment) {
}

bool Peer::RegisterAsync(
    chromeos::ErrorPtr* error,
    const std::string& uuid,
    const Time& last_seen,
    const CompletionAction& completion_callback) {
  if (!base::IsValidGUID(uuid)) {
    Error::AddTo(error,
                 FROM_HERE,
                 kPeerdErrorDomain,
                 errors::peer::kInvalidUUID,
                 "Invalid UUID for peer.");
    return false;
  }
  dbus_adaptor_.SetUUID(uuid);
  if (!SetLastSeen(error, last_seen)) { return false; }
  dbus_adaptor_.RegisterWithDBusObject(dbus_object_.get());
  dbus_object_->RegisterAsync(completion_callback);
  return true;
}

bool Peer::SetLastSeen(chromeos::ErrorPtr* error, const Time& last_seen) {
  if (!IsValidUpdateTime(error, last_seen)) {
    return false;
  }
  uint64_t milliseconds_since_epoch = 0;
  CHECK(TimeToMillisecondsSinceEpoch(last_seen, &milliseconds_since_epoch));
  dbus_adaptor_.SetLastSeen(milliseconds_since_epoch);
  return true;
}

std::string Peer::GetUUID() const {
  return dbus_adaptor_.GetUUID();
}

Time Peer::GetLastSeen() const {
  return TimeDelta::FromMilliseconds(dbus_adaptor_.GetLastSeen()) +
         Time::UnixEpoch();
}

bool Peer::IsValidUpdateTime(chromeos::ErrorPtr* error,
                             const base::Time& last_seen) const {
  uint64_t milliseconds_since_epoch = 0;
  if (!TimeToMillisecondsSinceEpoch(last_seen, &milliseconds_since_epoch)) {
    Error::AddTo(error,
                 FROM_HERE,
                 kPeerdErrorDomain,
                 errors::peer::kInvalidTime,
                 "Negative time update is invalid.");
    return false;
  }
  if (milliseconds_since_epoch < dbus_adaptor_.GetLastSeen()) {
    Error::AddTo(error,
                 FROM_HERE,
                 kPeerdErrorDomain,
                 errors::peer::kInvalidTime,
                 "Discarding update to last seen time as stale.");
    return false;
  }
  return true;
}

bool Peer::AddService(chromeos::ErrorPtr* error,
                      const string& service_id,
                      const Service::IpAddresses& addresses,
                      const map<string, string>& service_info,
                      const map<string, Any>& options) {
  if (services_.find(service_id) != services_.end()) {
    Error::AddToPrintf(error,
                       FROM_HERE,
                       kPeerdErrorDomain,
                       errors::peer::kDuplicateServiceID,
                       "Cannot add service with duplicate service ID %s.",
                       service_id.c_str());
    return false;
  }
  ObjectPath service_path(service_path_prefix_.value() +
                          std::to_string(++services_added_));
  // TODO(wiley): There is a potential race here.  If we remove the service
  //              too quickly, we race with DBus export completing.  We'll
  //              have to be careful in Service not to assume export has
  //              finished.
  scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
  unique_ptr<Service> new_service{new Service{
      bus_, dbus_object_->GetObjectManager().get(), service_path}};
  const bool success = new_service->RegisterAsync(
      error, GetUUID(), service_id, addresses, service_info, options,
      sequencer->GetHandler("Failed exporting service.", true));
  if (success) {
    services_.emplace(service_id, std::move(new_service));
    sequencer->OnAllTasksCompletedCall({});
  }
  return success;
}

bool Peer::RemoveService(chromeos::ErrorPtr* error,
                         const string& service_id) {
  if (services_.erase(service_id) == 0) {
    Error::AddTo(error,
                 FROM_HERE,
                 kPeerdErrorDomain,
                 errors::peer::kUnknownService,
                 "Unknown service id.");
    return false;
  }
  return true;
}

bool Peer::TimeToMillisecondsSinceEpoch(const Time& time, uint64_t* ret) const {
  int64_t time_diff = (time - Time::UnixEpoch()).InMilliseconds();
  if (time_diff < 0) {
    return false;
  }
  *ret = static_cast<uint64_t>(time_diff);
  return true;
}

}  // namespace peerd
