// Copyright 2015 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 LEADERD_GROUP_H_
#define LEADERD_GROUP_H_

#include <set>
#include <string>
#include <tuple>
#include <vector>

#include <base/macros.h>
#include <base/timer/timer.h>
#include <chromeos/dbus/async_event_sequencer.h>
#include <chromeos/dbus/dbus_service_watcher.h>
#include <chromeos/http/http_transport.h>

#include "leaderd/group_config.h"
#include "leaderd/org.chromium.leaderd.Group.h"

namespace chromeos {
namespace dbus_utils {
class ExportedObjectManager;
}  // dbus_utils
}  // chromeos

namespace leaderd {

// Represents a single group advertisement.
class Group : public org::chromium::leaderd::GroupInterface {
 public:
  using IpInfo = std::vector<std::tuple<std::vector<uint8_t>, uint16_t>>;
  using CompletionAction =
      chromeos::dbus_utils::AsyncEventSequencer::CompletionAction;

  class Delegate {
   public:
    virtual ~Delegate() = default;

    virtual void RemoveGroup(const std::string& group) = 0;
    virtual const std::string& GetUUID() const = 0;
    virtual IpInfo GetIPInfo(const std::string& peer_id) const = 0;
  };

  enum class State { WANDERER, FOLLOWER, LEADER };

  Group(const std::string& guid,
        std::unique_ptr<GroupConfig> config,
        const scoped_refptr<dbus::Bus>& bus,
        chromeos::dbus_utils::ExportedObjectManager* object_manager,
        const dbus::ObjectPath& path,
        const std::string& dbus_connection_id,
        const std::set<std::string>& peer_list,
        Delegate* delegate);
  void RegisterAsync(const CompletionAction& completion_callback);
  const dbus::ObjectPath& GetObjectPath() const;

  // DBus handlers
  bool LeaveGroup(chromeos::ErrorPtr* error) override;
  bool SetScore(chromeos::ErrorPtr* error, int32_t new_score) override;
  bool PokeLeader(chromeos::ErrorPtr* error) override;

  // The manager informs us when a peer is interested in who the leader is.
  void HandleLeaderDiscover(std::string* leader_id);
  // The manager informs us when we need to respond to a challenge from a peer.
  void HandleLeaderChallenge(const std::string& challenger_id,
                             int32_t challenger_score,
                             std::string* leader_id,
                             std::string* my_id);
  // The manager informs us of leadership announcements from our peers.
  bool HandleLeaderAnnouncement(const std::string& leader_id,
                                int32_t leader_score);

  // The manager informs us of changes in group membership.
  void AddPeer(const std::string& uuid);
  void RemovePeer(const std::string& uuid);
  void ClearPeers();

 private:
  friend class GroupTest;
  FRIEND_TEST(GroupTest, LeaderChallengeIsWellFormed);
  FRIEND_TEST(GroupTest, LeaderAnnouncementIsWellFormed);

  void OnDBusServiceDeath();
  void RemoveSoon();
  void RemoveNow();
  bool IsTheirScoreGreater(int32_t other_score,
                           const std::string& other_id) const;
  void SetRole(State state, const std::string& leader);
  void OnWandererTimeout();
  bool BuildApiUrls(const std::string& api_verb,
                    const std::string& peer_id,
                    std::vector<std::string>* urls) const;

  // These methods let us discover leaders.
  void AskPeersForLeaderInfo();
  void SendLeaderDiscover(const std::string& peer_id);
  void HandleLeaderDiscoverResponse(
      chromeos::http::RequestID request_id,
      std::unique_ptr<chromeos::http::Response> response);
  // These methods let us periodically challenge the leader to confirm fitness.
  void SendLeaderChallenge(const std::string& peer_id);
  void HandleLeaderChallengeResponse(
      chromeos::http::RequestID request_id,
      std::unique_ptr<chromeos::http::Response> response);
  void HandleLeaderChallengeFailure(chromeos::http::RequestID request_id,
                                    const chromeos::Error*);
  // These methods let us announce our leadership.  We ignore results.
  void AnnounceLeadership();
  void SendLeaderAnnouncement(const std::string& peer_id);

  // Used in tests.
  void ReplaceTimersWithMocksForTest(
      std::unique_ptr<base::Timer> wanderer_timer,
      std::unique_ptr<base::Timer> heartbeat_timer);
  void ReplaceHTTPTransportForTest(
      std::shared_ptr<chromeos::http::Transport> transport) {
    transport_ = transport;
  }

  const std::string guid_;
  const std::unique_ptr<GroupConfig> config_;
  const dbus::ObjectPath object_path_;
  std::unique_ptr<base::Timer> wanderer_timer_{
      new base::OneShotTimer<Group>()};
  std::unique_ptr<base::Timer> heartbeat_timer_{
      new base::RepeatingTimer<Group>()};

  // A set of UUIDs of the peers advertising this group.
  std::set<std::string> peers_;
  Delegate* delegate_;
  State state_{State::WANDERER};
  int32_t score_{0};
  uint64_t failed_challenges_{0};
  std::string leader_;
  std::shared_ptr<chromeos::http::Transport> transport_;

  org::chromium::leaderd::GroupAdaptor dbus_adaptor_{this};
  chromeos::dbus_utils::DBusObject dbus_object_;
  std::unique_ptr<chromeos::dbus_utils::DBusServiceWatcher> service_watcher_;

  base::WeakPtrFactory<Group> lifetime_factory_{this};
  base::WeakPtrFactory<Group> per_state_factory_{this};
  DISALLOW_COPY_AND_ASSIGN(Group);
};

}  // namespace leaderd

#endif  // LEADERD_GROUP_H_
