/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __VOM_OM_H__
#define __VOM_OM_H__

#include <memory>
#include <set>

#include "vom/client_db.hpp"
#include "vom/hw.hpp"

/**

The VPP Object Model (VOM) library.

Before we begin, a glossary of terms:
   - Agent or client: A user mode process that links to and uses the VOM library
     to programme VPP
   - VPP: A running instance of VPP
   - High Availability (HA): Scenarios where the client and/or VPP restart with
     minimal service interruption.
   - CReate, Update, Delete (CRUD): An API style where the producer issues
     notifications to changes to objects

The VOM is a C++ library that models entities in VPP as C++ classes. The
 relationships between VOM objects and VPP entities is not always 1:1. Some
 effort has been made to construct a higher level, more abstract API to VPP
 programming*.
The client programming model is simple (or at least I intended it to be..). The
client deals in ‘desired’ state, that is, it expresses the objects it wants to
exists (in VPP) and the properties that the object should have, i.e**;
    Interface af1(“my-af-packet-1”, AFPACKET, admin::UP);
Then the client ‘writes’ this object into the ‘model’
    OM::write(“clients-thing-1”, af1);

“clients-thing-1” is a description of the entity within the client’s domain that
‘owns’ (or has locked or has a reference to) the VOM object. There can be many
owners of each VOM object. It will be the last owner’s update that will be
programmed in VPP. This model means that the client is not burdened with
maintaining which of its objects have created which VOM objects. If the client
is itself driven by a CRUD API, then create notifications are implemented as
 above. Update notifications add two extra statements;
    OM::mark(“clients-thing-1”);
    … do writes ….
    OM::sweep(“clients-thing-1”);
These ‘mark’ and ‘sweep’ statements are indications to OM that firstly, indicate
that all the objects owned by “clients-thing-1” are now stale, i.e that the
client may no longer need them. If one of the subsequent writes should update a
stale object, then it is no longer stale. The sweep statement will ‘remove’ all
the remaining stale objects. In this model, the client does not need to maintain
the mapping of VOM objects to its own objects – it can simply express what it
needs now.
The delete notification is simply:
     OM::remove(“clients-thing-1”);
Which will remove all the objects in VOM that are owned by “clients-thing-1”.
Where ‘remove’ in this sense means unlock and unreference, the VOM object, and
VPP state, will only be truly removed once there are no more owners. This is
equivalent to a mark & sweep with no intermediate writes.

To provide this client side model the VOM is a stateful library, meaning that
for each entity it creates in VPP, VOM maintains its own representation of that
object. VOM can therefore be memory hungry. The desired state is expressed by
the client, the ‘actual’ state is maintained by VOM. VOM will consolidate the
two states when the client writes to the OM and thus issue VPP only the changes
required.

The concepts of ownership and statefulness also allow the support for HA
scenarios.
VPP restart: When VPP restarts, VOM will reconnect and ‘replay’ its state, in
dependency order, to VPP. The client does not need to regenerate its desired
state.
Client restart: when the client restarts, VOM will read/dump the current state
of all VPP objects and store them in the OM owned by the special owner “boot”.
As the client reprogrammes its desired state, objects will become owned by both
the boot process and the client. At the point in time, as determined by the
client, all stale state, that owned only by boot, can be purged. Hence the
system reaches the correct final state, with no interruption to VPP forwarding.


Basic Design:

Each object in VOM (i.e. an interface, route, bridge-domain, etc) is stored in a
per-type object database, with an object-type specific key. This ‘singular’ DB
has a value-type of a weak pointer to the object. I use the term ‘singular’ to
refer to the instance of the object stored in these databases, to be distinct
from the instances the client constructs to represent desired state.
The ‘client’ DB maintains the mapping of owner to object. The value type of the
client DB is a shared pointer to the singular instance of the owned object.
Once all the owners are gone, and all the shared pointers are destroyed, the
singular instance is also destroyed.

Each VOM object has some basic behaviour:
  update: issue to VPP an update to this object’s state. This could include the
          create
  sweep: delete the VPP entity – called when the object is destroyed.
  replay: issue to VPP all the commands needed to re-programme (VPP restart HA
          scenario)
  populate: read state from VPP and add it to the OM (client restart HA
scenario)

The object code is boiler-plate, in some cases (like the ACLs) even template.
The objects are purposefully left as simple, functionality free as possible.

Communication with VPP is through a ‘queue’ of ‘commands’. A command is
essentially an object wrapper around a VPP binary API call (although we do use
the VAPI C++ bindings too). Commands come in three flavours:
  RPC: do this; done.
  DUMP: give me all of these things; here you go
  EVENT; tell me about these events; here’s one …. Here’s one…. Oh here’s
         another….. etc.

RPC and DUMP commands are handled synchronously. Therefore on return from
OM::write(…) VPP has been issued with the request and responded. EVENTs are
asynchronous and will be delivered to the listeners in a different thread – so
beware!!

* As such VOM provides some level of insulation to the changes to the VPP
  binary API.
** some of the type names are shorten for brevity’s sake.

*/
namespace VOM {
/**
 * The interface to writing objects into VPP OM.
 */
class OM
{
public:
  /**
   * A class providing the RAII pattern for mark and sweep
   */
  class mark_n_sweep
  {
  public:
    /**
     * Constructor - will call mark on the key
     */
    mark_n_sweep(const client_db::key_t& key);

    /**
     * Destructor - will call sweep on the key
     */
    ~mark_n_sweep();

  private:
    /**
     * no copies
     */
    mark_n_sweep(const mark_n_sweep& ms) = delete;

    /**
     * The client whose state we are guarding.
     */
    client_db::key_t m_key;
  };

  /**
   * Init
   */
  static void init();

  /**
   * populate the OM with state read from HW.
   */
  static void populate(const client_db::key_t& key);

  /**
   * Mark all state owned by this key as stale
   */
  static void mark(const client_db::key_t& key);

  /**
   * Sweep all the key's objects that are stale
   */
  static void sweep(const client_db::key_t& key);

  /**
   * Replay all of the objects to HW.
   */
  static void replay(void);

  /**
   * Make the State in VPP reflect the expressed desired state.
   *  But don't call the HW - use this whilst processing dumped
   *  data from HW
   */
  template <typename OBJ>
  static rc_t commit(const client_db::key_t& key, const OBJ& obj)
  {
    rc_t rc = rc_t::OK;

    HW::disable();
    rc = OM::write(key, obj);
    HW::enable();

    return (rc);
  }

  /**
   * Make the State in VPP reflect the expressed desired state.
   *  After processing all the objects in the queue, in FIFO order,
   *  any remaining state owned by the client_db::key_t is purged.
   * This is a template function so the object's update() function is
   * always called with the derived type.
   */
  template <typename OBJ>
  static rc_t write(const client_db::key_t& key, const OBJ& obj)
  {
    rc_t rc = rc_t::OK;

    /*
     * Find the singular instance another owner may have created.
     * this always returns something.
     */
    std::shared_ptr<OBJ> inst = obj.singular();

    /*
     * Update the existing object with the new desired state
     */
    inst->update(obj);

    /*
     * Find if the object already stored on behalf of this key.
     * and mark them stale
     */
    object_ref_list& objs = m_db->find(key);

    /*
     * Iterate through this list to find a matchin' object
     * to the one requested.
     */
    auto match_ptr = [inst](const object_ref& oref) {
      return (inst == oref.obj());
    };
    auto it = std::find_if(objs.begin(), objs.end(), match_ptr);

    if (it != objs.end()) {
      /*
       * yes, this key already owns this object.
       */
      it->clear();
    } else {
      /*
       * Add the singular instance to the owners list
       */
      objs.insert(object_ref(inst));
    }

    return (HW::write());
  }

  /**
   * Remove all object in the OM referenced by the key
   */
  static void remove(const client_db::key_t& key);

  /**
   * Print each of the object in the DB into the stream provided
   */
  static void dump(const client_db::key_t& key, std::ostream& os);

  /**
   * Print each of the KEYS
   */
  static void dump(std::ostream& os);

  /**
   * Class definition for listeners to OM events
   */
  class listener
  {
  public:
    listener() = default;
    virtual ~listener() = default;

    /**
     * Handle a populate event
     */
    virtual void handle_populate(const client_db::key_t& key) = 0;

    /**
     * Handle a replay event
     */
    virtual void handle_replay() = 0;

    /**
     * Get the sortable Id of the listener
     */
    virtual dependency_t order() const = 0;

    /**
     * less than operator for set sorting
     */
    bool operator<(const listener& listener) const
    {
      return (order() < listener.order());
    }
  };

  /**
   * Register a listener of events
   */
  static bool register_listener(listener* listener);

private:
  /**
   * Database of object state created for each key
   */
  static client_db* m_db;

  /**
   * Comparator to keep the pointers to listeners in sorted order
   */
  struct listener_comparator_t
  {
    bool operator()(const listener* l1, const listener* l2) const
    {
      return (l1->order() < l2->order());
    }
  };

  /**
   * convenient typedef for the sorted set of listeners
   */
  typedef std::multiset<listener*, listener_comparator_t> listener_list;

  /**
   * The listeners for events
   */
  static std::unique_ptr<listener_list> m_listeners;
};
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "mozilla")
 * End:
 */

#endif
