// Copyright 2016 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 PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_REPOSITORY_H_
#define PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_REPOSITORY_H_

#include <map>
#include <set>
#include <string>

#include <fuchsia/modular/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/macros.h>

#include "peridot/bin/context_engine/index.h"

namespace modular {

class ContextDebug;
class ContextDebugImpl;

// This class represents a "multiparent hierarchy", which is another way
// of saying a directed graph that cannot have any cycles.
// TODO(thatguy): Actually enforce the no cycles constraint :).
class ContextGraph {
 public:
  using Id = std::string;

  ContextGraph();
  virtual ~ContextGraph();

  // Adds a graph edge from |from| to |to|.
  void AddEdge(const Id& from, const Id& to);

  // Removes the node |id| and removes any incoming or outgoing edges.
  // TODO(thatguy): Decide what to do about orphaned children.
  void Remove(const Id& id);

  std::set<Id> GetParents(const Id& id) const;

  // Returns all |id|'s children and their children, recursively.
  std::set<Id> GetChildrenRecursive(const Id& id) const;

  // Returns all ancestors for |id|, guaranteeing that all node ids appear in
  // the return value before their children (ie, in order of seniority).
  std::vector<Id> GetAncestors(const Id& id) const;

 private:
  // From node to its parents.
  std::map<Id, std::set<Id>> parents_;
  // From parent to its immediate children.
  std::map<Id, std::set<Id>> children_;
};

// Stores a graph of fuchsia::modular::ContextValue structs (values). Supports
// fetching lists of values based on a) the value's type and b)
// fuchsia::modular::ContextMetadata fields.
//
// The graph structure is used to represent value namespaces or scope, although
// the exact meaning or what concepts are represented is up to the client. When
// a value is queried against and returned, its metadata is "flattened" with
// its ancestors' metadata. For example, if an ENTITY value is a child of a
// MODULE value, the ENTITY value will inherit the MODULE value's metadata (ie,
// the |mod| field of the fuchsia::modular::ContextMetadata struct).
class ContextRepository {
  struct ValueInternal;
  struct Subscription;
  struct InProgressUpdate;

 public:
  using Id = ContextIndex::Id;
  using IdAndVersionSet = std::set<std::pair<Id, uint32_t>>;

  ContextRepository();
  ~ContextRepository();

  bool Contains(const Id& id) const;
  Id Add(fuchsia::modular::ContextValue value);
  Id Add(const Id& parent_id, fuchsia::modular::ContextValue value);
  void Update(const Id& id, fuchsia::modular::ContextValue value);
  void Remove(const Id& id);

  // Returns a copy of the fuchsia::modular::ContextValue for |id|. Returns a
  // null |fuchsia::modular::ContextValuePtr| if |id| is not valid.
  fuchsia::modular::ContextValuePtr Get(const Id& id) const;

  // Returns a copy of the fuchsia::modular::ContextValue for |id|, with
  // metadata merged from ancestors. Returns a null
  // |fuchsia::modular::ContextValuePtr| if |id| is not valid.
  fuchsia::modular::ContextValuePtr GetMerged(const Id& id) const;

  std::set<Id> Select(const fuchsia::modular::ContextSelector& selector);

  // Returns the current requested values for the given query as a context
  // update.
  fuchsia::modular::ContextUpdate Query(const fuchsia::modular::ContextQuery& query);

  // Does not take ownership of |listener|. |listener| must remain valid until
  // RemoveSubscription() is called with the returned Id.
  Id AddSubscription(fuchsia::modular::ContextQuery query,
                     fuchsia::modular::ContextListener* listener,
                     fuchsia::modular::SubscriptionDebugInfo debug_info);
  void RemoveSubscription(Id id);

  // Like AddSubscription above, but takes ownership of the FIDL service proxy
  // object, |listener|. The subscription is automatically removed when
  // |listener| experiences a connection error.
  void AddSubscription(fuchsia::modular::ContextQuery query,
                       fuchsia::modular::ContextListenerPtr listener,
                       fuchsia::modular::SubscriptionDebugInfo debug_info);

  ContextDebugImpl* debug();
  void AddDebugBinding(fidl::InterfaceRequest<fuchsia::modular::ContextDebug> request);

 private:
  Id AddInternal(const Id& parent_id, fuchsia::modular::ContextValue value);
  void RecomputeMergedMetadata(ValueInternal* value);
  void ReindexAndNotify(InProgressUpdate update);
  void QueryAndMaybeNotify(Subscription* subscription, bool force);
  std::pair<fuchsia::modular::ContextUpdate, IdAndVersionSet> QueryInternal(
      const fuchsia::modular::ContextQuery& query);

  // Keyed by internal id.
  std::map<Id, ValueInternal> values_;
  ContextGraph graph_;

  // A map of Id (int) to Subscription.
  std::map<Id, Subscription> subscriptions_;

  ContextIndex index_;

  friend class ContextDebugImpl;
  std::unique_ptr<ContextDebugImpl> debug_;
  fidl::BindingSet<fuchsia::modular::ContextDebug> debug_bindings_;

  FXL_DISALLOW_COPY_AND_ASSIGN(ContextRepository);
};

struct ContextRepository::ValueInternal {
  // The contents of |value.meta| merged with metadata from all
  // of this value's ancestors.
  Id id;
  fuchsia::modular::ContextMetadata merged_metadata;
  fuchsia::modular::ContextValue value;
  uint32_t version;  // Incremented on change.
};

struct ContextRepository::Subscription {
  fuchsia::modular::ContextQuery query;
  fuchsia::modular::ContextListener* listener;  // Optionally owned by |listener_storage|.
  fuchsia::modular::ContextListenerPtr listener_storage;
  fuchsia::modular::SubscriptionDebugInfo debug_info;
  // The set of value id and version we sent the last time we notified
  // |listener|. Used to calculate if a new update is different.
  IdAndVersionSet last_update;
};

// Holds interim values necessary for processing an update to at least one
// context value.
struct ContextRepository::InProgressUpdate {
  // These values are having their values added or updated.
  std::vector<ValueInternal*> updated_values;
  // These values are being removed.
  std::vector<ValueInternal> removed_values;
};

}  // namespace modular

#endif  // PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_REPOSITORY_H_
