// Copyright (c) 2013 The Chromium 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 NET_DNS_MDNS_CACHE_H_
#define NET_DNS_MDNS_CACHE_H_

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

#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "net/base/net_export.h"

namespace net {

class ParsedDnsRecord;
class RecordParsed;

// mDNS Cache
// This is a cache of mDNS records. It keeps track of expiration times and is
// guaranteed not to return expired records. It also has facilities for timely
// record expiration.
class NET_EXPORT_PRIVATE MDnsCache {
 public:
  // Key type for the record map. It is a 3-tuple of type, name and optional
  // value ordered by type, then name, then optional value. This allows us to
  // query for all records of a certain type and name, while also allowing us
  // to set records of a certain type, name and optionally value as unique.
  class Key {
   public:
    Key(unsigned type, const std::string& name, const std::string& optional);
    Key(const Key&);
    Key& operator=(const Key&);
    ~Key();
    bool operator<(const Key& key) const;
    bool operator==(const Key& key) const;

    unsigned type() const { return type_; }
    const std::string& name() const  { return name_; }
    const std::string& optional() const { return optional_; }

    // Create the cache key corresponding to |record|.
    static Key CreateFor(const RecordParsed* record);
   private:
    unsigned type_;
    std::string name_;
    std::string optional_;
  };

  typedef base::Callback<void(const RecordParsed*)> RecordRemovedCallback;

  enum UpdateType {
    RecordAdded,
    RecordChanged,
    NoChange
  };

  MDnsCache();
  ~MDnsCache();

  // Return value indicates whether the record was added, changed
  // (existed previously with different value) or not changed (existed
  // previously with same value).
  UpdateType UpdateDnsRecord(scoped_ptr<const RecordParsed> record);

  // Check cache for record with key |key|. Return the record if it exists, or
  // NULL if it doesn't.
  const RecordParsed* LookupKey(const Key& key);

  // Return records with type |type| and name |name|. Expired records will not
  // be returned. If |type| is zero, return all records with name |name|.
  void FindDnsRecords(unsigned type,
                      const std::string& name,
                      std::vector<const RecordParsed*>* records,
                      base::Time now) const;

  // Remove expired records, call |record_removed_callback| for every removed
  // record.
  void CleanupRecords(base::Time now,
                      const RecordRemovedCallback& record_removed_callback);

  // Returns a time less than or equal to the next time a record will expire.
  // Is updated when CleanupRecords or UpdateDnsRecord are called. Returns
  // base::Time when the cache is empty.
  base::Time next_expiration() const { return next_expiration_; }

  // Remove a record from the cache.  Returns a scoped version of the pointer
  // passed in if it was removed, scoped null otherwise.
  scoped_ptr<const RecordParsed> RemoveRecord(const RecordParsed* record);

  void Clear();

 private:
  typedef std::map<Key, const RecordParsed*> RecordMap;

  // Get the effective expiration of a cache entry, based on its creation time
  // and TTL. Does adjustments so entries with a TTL of zero will have a
  // nonzero TTL, as explained in RFC 6762 Section 10.1.
  static base::Time GetEffectiveExpiration(const RecordParsed* entry);

  // Get optional part of the DNS key for shared records. For example, in PTR
  // records this is the pointed domain, since multiple PTR records may exist
  // for the same name.
  static std::string GetOptionalFieldForRecord(
      const RecordParsed* record);

  RecordMap mdns_cache_;

  base::Time next_expiration_;

  DISALLOW_COPY_AND_ASSIGN(MDnsCache);
};

}  // namespace net

#endif  // NET_DNS_MDNS_CACHE_H_
