// 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.

#ifndef PEERD_PEER_H_
#define PEERD_PEER_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <stdint.h>

#include <brillo/any.h>
#include <brillo/dbus/dbus_object.h>
#include <brillo/dbus/exported_property_set.h>
#include <brillo/errors/error.h>
#include <dbus/bus.h>
#include <gtest/gtest_prod.h>

#include "peerd/org.chromium.peerd.Peer.h"
#include "peerd/service.h"
#include "peerd/typedefs.h"

namespace peerd {

namespace errors {
namespace peer {

extern const char kInvalidUUID[];
extern const char kInvalidTime[];
extern const char kUnknownService[];
extern const char kDuplicateServiceID[];

}  // namespace peer
}  // namespace errors

// Exposes a Peer interface over DBus.  We use this class to represent
// ourself over DBus to interested viewers.  We also use it to represent
// remote peers that we've discovered over various mediums.
class Peer : public org::chromium::peerd::PeerInterface {
 public:
  Peer(const scoped_refptr<dbus::Bus>& bus,
       brillo::dbus_utils::ExportedObjectManager* object_manager,
       const dbus::ObjectPath& path);
  ~Peer() override = default;
  bool RegisterAsync(
      brillo::ErrorPtr* error,
      const std::string& uuid,
      const base::Time& last_seen,
      const CompletionAction& completion_callback);

  virtual std::string GetUUID() const;
  virtual base::Time GetLastSeen() const;
  // Returns false on failure.
  virtual bool SetLastSeen(brillo::ErrorPtr* error,
                           const base::Time& last_seen);

 protected:
  // Add a service to be exported by this peer.  Can fail if this peer
  // is already advertising a service with |service_id|, or if any of the
  // arguments passed to service are found to be invalid.
  // Returns false on error, and can optionally provide detailed error
  // information in |error|.
  virtual bool AddService(
      brillo::ErrorPtr* error,
      const std::string& service_id,
      const Service::IpAddresses& addresses,
      const std::map<std::string, std::string>& service_info,
      const std::map<std::string, brillo::Any>& options);
  // Remove a service advertised by this peer.  Can fail if no service with id
  // |service_id| is in this peer.
  virtual bool RemoveService(brillo::ErrorPtr* error,
                             const std::string& service_id);

  bool IsValidUpdateTime(brillo::ErrorPtr* error,
                         const base::Time& last_seen) const;
  std::map<std::string, std::unique_ptr<Service>> services_;

 private:
  bool TimeToMillisecondsSinceEpoch(const base::Time& time,
                                    uint64_t* ret) const;
  scoped_refptr<dbus::Bus> bus_;
  size_t services_added_{0};
  org::chromium::peerd::PeerAdaptor dbus_adaptor_{this};
  std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object_;
  dbus::ObjectPath service_path_prefix_;

  friend class PeerTest;
  friend class MockPeer;
  FRIEND_TEST(PeerTest, ShouldRejectDuplicateServiceID);
  DISALLOW_COPY_AND_ASSIGN(Peer);
};

}  // namespace peerd

#endif  // PEERD_PEER_H_
