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

#include <string>

#include <dbus/object_path.h>

#include "peerd/dbus_constants.h"

using chromeos::dbus_utils::AsyncEventSequencer;
using chromeos::dbus_utils::ExportedObjectManager;
using peerd::technologies::tech_t;
using std::string;
using std::to_string;
using std::unique_ptr;

namespace peerd {

PeerManagerImpl::PeerManagerImpl(const scoped_refptr<dbus::Bus> bus,
                                 ExportedObjectManager* object_manager)
    : bus_(bus),
      object_manager_(object_manager) {
}

void PeerManagerImpl::OnPeerDiscovered(const string& peer_id,
                                       const base::Time& last_seen,
                                       tech_t which_technology) {
  VLOG(1) << "Discovered peer=" << peer_id;
  auto it = peers_.find(peer_id);
  if (it != peers_.end()) {
    it->second->UpdateFromAdvertisement(last_seen, which_technology);
    return;
  }
  dbus::ObjectPath path{
      string(dbus_constants::kPeerPrefix) + to_string(++peers_discovered_)};
  unique_ptr<DiscoveredPeer> peer{new DiscoveredPeer{
      bus_, object_manager_, path, which_technology}};
  scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
  const bool registered = peer->RegisterAsync(
      nullptr, peer_id, last_seen,
      sequencer->GetHandler("Failed to expose DiscoveredPeer.", true));
  sequencer->OnAllTasksCompletedCall({});
  if (registered) {
    peers_[peer_id].swap(peer);
  } else {
    LOG(INFO) << "Discovered corrupted peer advertisement; discarding it.";
  }
}

void PeerManagerImpl::OnServiceDiscovered(const string& peer_id,
                                          const string& service_id,
                                          const Service::ServiceInfo& info,
                                          const Service::IpAddresses& addresses,
                                          const base::Time& last_seen,
                                          tech_t which_technology) {
  auto it = peers_.find(peer_id);
  if (it == peers_.end()) {
    // A service was found that corresponds to no particular peer.
    // We could just silently add a peer entry here, or we can discard the
    // service.  Lets discard the service until it is known that we need to
    // support this case.
    LOG(WARNING) << "Found service=" << service_id << " but had no peer="
                 << peer_id;
    return;
  }
  VLOG(1) << "Updating service=" << service_id
          << " from technology=" << which_technology;
  it->second->UpdateService(service_id, addresses, info,
                            last_seen, which_technology);
}

void PeerManagerImpl::OnPeerRemoved(const string& peer_id,
                                    tech_t which_technology) {
  auto it = peers_.find(peer_id);
  if (it == peers_.end()) {
    LOG(WARNING) << "Tried to remove technology=" << which_technology
                 << " from peer=" << peer_id
                 << " that was never discovered.";
    return;
  }
  it->second->RemoveTechnology(which_technology);
  if (it->second->GetTechnologyCount() == 0) {
    peers_.erase(it);
  }
}

void PeerManagerImpl::OnServiceRemoved(const string& peer_id,
                                       const string& service_id,
                                       tech_t which_technology) {
  auto it = peers_.find(peer_id);
  if (it == peers_.end()) {
    LOG(WARNING) << "Tried to remove service from peer that was "
                 << "never discovered: " << peer_id;
    return;
  }
  it->second->RemoveTechnologyFromService(service_id, which_technology);
}

void PeerManagerImpl::OnTechnologyShutdown(tech_t which_technology) {
  auto it = peers_.begin();
  while (it != peers_.end()) {
    it->second->RemoveTechnology(which_technology);
    if (it->second->GetTechnologyCount() == 0) {
      it = peers_.erase(it);
    } else {
      ++it;
    }
  }
}

}  // namespace peerd
