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

#include <bitset>
#include <limits>
#include <string>

using brillo::dbus_utils::ExportedObjectManager;
using peerd::technologies::TechnologySet;
using peerd::technologies::Technology;
using std::bitset;
using std::string;

namespace peerd {

DiscoveredPeer::DiscoveredPeer(const scoped_refptr<dbus::Bus>& bus,
                               ExportedObjectManager* object_manager,
                               const dbus::ObjectPath& path,
                               Technology which_technology)
    : Peer(bus, object_manager, path) {
  discovered_on_technologies_.set(which_technology);
}

void DiscoveredPeer::UpdateFromAdvertisement(const base::Time& last_seen,
                                             Technology technology) {
  if (!IsValidUpdateTime(nullptr, last_seen)) { return; }
  SetLastSeen(nullptr, last_seen);
  discovered_on_technologies_.set(technology);
}

void DiscoveredPeer::UpdateService(const std::string& service_id,
                                   const Service::IpAddresses& addresses,
                                   const Service::ServiceInfo& info,
                                   const base::Time& last_seen,
                                   Technology technology) {
  if (!discovered_on_technologies_.test(technology)) {
    // We're updating a service for a technology, even though we haven't found
    // this peer on that technology.  We could allow this, but lets not until
    // we know this is valid use case.
    LOG(WARNING) << "Found service=" << service_id
                 << " on technology=" << technology
                 << " but had not previously found a peer on that service.";
    return;
  }
  // Regardless of what we do with the service update, we have new information
  // about this peer, so this counts as "seeing it."
  SetLastSeen(nullptr, last_seen);  // Ignore errors.
  auto service_it = services_.find(service_id);
  if (service_it != services_.end()) {
    auto metadata_it = service_metadata_.find(service_id);
    CHECK(metadata_it != service_metadata_.end());
    if (last_seen <  metadata_it->second.last_seen) {
      LOG(WARNING) << "Discarding stale service update.";
      return;
    }
    if (!service_it->second->Update(nullptr, addresses, info, {})) {
      LOG(WARNING) << "Discarding invalid service update.";
      return;
    }
    metadata_it->second.technology.set(technology);
    metadata_it->second.last_seen = last_seen;
    return;
  }
  // A new service is discovered!  Exposed it over DBus and update our metadata.
  if (!Peer::AddService(nullptr, service_id, addresses, info, {})) {
    LOG(WARNING) << "Failed to publish discovered service over DBus.";
    return;
  }
  TechnologySet service_tech;
  service_tech.set(technology);
  service_metadata_[service_id] = {std::move(service_tech), last_seen};
}

void DiscoveredPeer::RemoveTechnology(Technology technology) {
  discovered_on_technologies_.reset(technology);
  auto it = service_metadata_.begin();
  while (it != service_metadata_.end()) {
    it->second.technology.reset(technology);
    if (it->second.technology.none()) {
      RemoveService(nullptr, it->first);
      it = service_metadata_.erase(it);
    } else {
      ++it;
    }
  }
}

void DiscoveredPeer::RemoveTechnologyFromService(const std::string& service_id,
                                                 Technology technology) {
  auto it = service_metadata_.find(service_id);
  if (it == service_metadata_.end()) {
    LOG(WARNING) << "Failed to find service previously discovered over "
                 << "technology=" << technology;
    return;
  }
  it->second.technology.reset(technology);
  // Remove this service if there are no technologies claiming to see it.
  if (it->second.technology.none()) {
    service_metadata_.erase(it);
    RemoveService(nullptr, service_id);
  }
}

size_t DiscoveredPeer::GetTechnologyCount() const {
  return discovered_on_technologies_.count();
}

}  // namespace peerd
