// Copyright 2017 The Fuchsia 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 SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_RESOURCE_RENEWER_H_
#define SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_RESOURCE_RENEWER_H_

#include <memory>
#include <queue>
#include <string>
#include <unordered_set>
#include <vector>

#include "garnet/lib/inet/ip_port.h"
#include "src/connectivity/network/mdns/service/mdns_agent.h"

namespace mdns {

// Renews resources by querying them before their TTLs expire.
//
// |ResourceRenewer| renews a set of resources as directed by calls to its
// |Renew| method.
//
// |ResourceRenewer| queries for a resource at 80%, 85%, 90% and 95% of the
// resource's TTL. If a resource is renewed, the renewer forgets about the
// resource until asked again to renew it. If a resource's TTL expires,
// |ResourceRenewer| sends a resource record to all the agents with
// a TTL of zero, signalling that the resource should be deleted and forgets
// about the resource. If a resource is explicitly deleted (a resource
// record arrives with TTL 0), |ResourceRenewer| will not attempt to renew the
// resource.
//
// Agents that need a resource record renewed call |Renew| on the host, which
// then calls |Renew| on the |ResourceRenewer|. Agents must continue to renew
// incoming resources as long as they want renewals to occur. When an agent
// loses interest in a record, it should imply stop renewing the incoming
// resource records. This approach will cause some unneeded renewals, but avoids
// difficult cleanup issues associated with a persistent renewal scheme.
class ResourceRenewer : public MdnsAgent {
 public:
  ResourceRenewer(MdnsAgent::Host* host);

  ~ResourceRenewer() override;

  // Attempts to renew |resource| before its TTL expires.
  void Renew(const DnsResource& resource);

  // MdnsAgent overrides.
  void ReceiveResource(const DnsResource& resource,
                       MdnsResourceSection section) override;

  void Quit() override;

 private:
  // All Entry objects are represented in both |entries_| and |schedule_|. We're
  // using raw pointers, so the destructor must delete all Entry objects
  // explicitly.

  struct Entry {
    static constexpr uint32_t kFirstQueryPerThousand = 800;
    static constexpr uint32_t kQueryIntervalPerThousand = 50;
    static constexpr uint32_t kQueriesToAttempt = 4;

    Entry(const std::string& name, DnsType type) : name_(name), type_(type) {}

    std::string name_;
    DnsType type_;

    fxl::TimePoint time_;
    fxl::TimeDelta interval_;
    uint32_t queries_remaining_;

    // Time value used for |schedule|. In some cases, we want to postpone a
    // query or expiration that was previously scheduled. In this case, |time_|
    // will be increased, but |schedule_time_| will remain unchanged. When the
    // entry comes up in the schedule, the entry should be rescheduled if
    // |time_| is different from |schedule_time_|.
    fxl::TimePoint schedule_time_;

    bool delete_ = false;

    // Sets |time_|, |interval_| and |queries_remaining_| to their initial
    // values to initiate the eventual renewal of the resource.
    void SetFirstQuery(uint32_t time_to_live);

    // Updates |time_| and |queries_remaining_| for the purposes of scheduling
    // the next query or expiration.
    void SetNextQueryOrExpiration();
  };

  struct Hash {
    size_t operator()(const std::unique_ptr<Entry>& m) const {
      FXL_DCHECK(m);
      return std::hash<std::string>{}(m->name_) ^
             std::hash<DnsType>{}(m->type_);
    }
  };

  struct Equals {
    size_t operator()(const std::unique_ptr<Entry>& a,
                      const std::unique_ptr<Entry>& b) const {
      FXL_DCHECK(a);
      FXL_DCHECK(b);
      return a->name_ == b->name_ && a->type_ == b->type_;
    }
  };

  struct LaterScheduleTime {
    size_t operator()(const Entry* a, const Entry* b) {
      FXL_DCHECK(a != nullptr);
      FXL_DCHECK(b != nullptr);
      return a->schedule_time_ > b->schedule_time_;
    }
  };

  // Sends current renewals and schedules another call to |SendRenewals|, as
  // appropriate.
  void SendRenewals();

  void Schedule(Entry* entry);

  void EraseEntry(Entry* entry);

  std::unordered_set<std::unique_ptr<Entry>, Hash, Equals> entries_;
  std::priority_queue<Entry*, std::vector<Entry*>, LaterScheduleTime> schedule_;
};

}  // namespace mdns

#endif  // SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_RESOURCE_RENEWER_H_
