/*
    This file is part of TON Blockchain Library.
    TON Blockchain Library is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.
    TON Blockchain Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.
    You should have received a copy of the GNU Lesser General Public License
    along with TON Blockchain Library.  If not, see .
*/
#pragma once
#include "full-node.h"
namespace ton::validator::fullnode {
class FullNodePrivateOverlayV2 : public td::actor::Actor {
 public:
  void process_broadcast(PublicKeyHash src, ton_api::tonNode_blockBroadcast &query);
  void process_broadcast(PublicKeyHash src, ton_api::tonNode_newShardBlockBroadcast &query);
  template 
  void process_broadcast(PublicKeyHash, T &) {
    VLOG(FULL_NODE_WARNING) << "dropping unknown broadcast";
  }
  void receive_broadcast(PublicKeyHash src, td::BufferSlice query);
  void send_shard_block_info(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data);
  void send_broadcast(BlockBroadcast broadcast);
  void start_up() override;
  void tear_down() override;
  void destroy() {
    stop();
  }
  FullNodePrivateOverlayV2(adnl::AdnlNodeIdShort local_id, ShardIdFull shard, std::vector nodes,
                           std::vector senders, FileHash zero_state_file_hash,
                           td::actor::ActorId keyring, td::actor::ActorId adnl,
                           td::actor::ActorId rldp, td::actor::ActorId rldp2,
                           td::actor::ActorId overlays,
                           td::actor::ActorId validator_manager)
      : local_id_(local_id)
      , shard_(shard)
      , nodes_(std::move(nodes))
      , senders_(std::move(senders))
      , zero_state_file_hash_(zero_state_file_hash)
      , keyring_(keyring)
      , adnl_(adnl)
      , rldp_(rldp)
      , rldp2_(rldp2)
      , overlays_(overlays)
      , validator_manager_(validator_manager) {
  }
 private:
  adnl::AdnlNodeIdShort local_id_;
  ShardIdFull shard_;
  std::vector nodes_;
  std::vector senders_;
  FileHash zero_state_file_hash_;
  td::actor::ActorId keyring_;
  td::actor::ActorId adnl_;
  td::actor::ActorId rldp_;
  td::actor::ActorId rldp2_;
  td::actor::ActorId overlays_;
  td::actor::ActorId validator_manager_;
  bool inited_ = false;
  overlay::OverlayIdFull overlay_id_full_;
  overlay::OverlayIdShort overlay_id_;
  UnixTime created_at_ = (UnixTime)td::Clocks::system();
  void try_init();
  void init();
  void get_stats_extra(td::Promise promise);
};
class FullNodePrivateBlockOverlays {
 public:
  td::actor::ActorId choose_overlay(ShardIdFull shard);
  void update_overlays(td::Ref state, std::set my_adnl_ids,
                       const FileHash& zero_state_file_hash, const td::actor::ActorId& keyring,
                       const td::actor::ActorId& adnl, const td::actor::ActorId& rldp,
                       const td::actor::ActorId& rldp2,
                       const td::actor::ActorId& overlays,
                       const td::actor::ActorId& validator_manager);
 private:
  struct Overlays {
    struct ShardOverlay {
      td::actor::ActorOwn overlay_;
      std::vector nodes_, senders_;
      bool is_sender_ = false;
    };
    std::map overlays_;
  };
  std::map id_to_overlays_;  // local_id -> overlays
};
}  // namespace ton::validator::fullnode