/*
 * 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_GBP_CONTRACT_H__
#define __VOM_GBP_CONTRACT_H__

#include "vom/acl_l3_list.hpp"
#include "vom/gbp_rule.hpp"
#include "vom/gbp_types.hpp"
#include "vom/interface.hpp"
#include "vom/singular_db.hpp"
#include "vom/types.hpp"

namespace VOM {

/**
 * A entry in the ARP termination table of a Bridge Domain
 */
class gbp_contract : public object_base
{
public:
  /**
   * set of gbp rules
   */
  typedef std::set<gbp_rule> gbp_rules_t;

  /**
   * The key for a contract is the pair of EPG-IDs
   */
  typedef std::tuple<scope_t, sclass_t, sclass_t> key_t;

  /**
   * A set of allowed ethertypes
   */
  typedef std::set<ethertype_t> ethertype_set_t;

  /**
   * Construct a GBP contract
   */
  gbp_contract(scope_t scope,
               sclass_t sclass,
               sclass_t dclass,
               const ACL::l3_list& acl,
               const gbp_rules_t& gpb_rules,
               const ethertype_set_t& allowed_ethertypes);

  /**
   * Copy Construct
   */
  gbp_contract(const gbp_contract& r);

  /**
   * Destructor
   */
  ~gbp_contract();

  /**
   * Return the object's key
   */
  const key_t key() const;

  /**
   * comparison operator
   */
  bool operator==(const gbp_contract& bdae) const;

  /**
   * Return the matching 'singular instance'
   */
  std::shared_ptr<gbp_contract> singular() const;

  /**
   * Find the instnace of the bridge_domain domain in the OM
   */
  static std::shared_ptr<gbp_contract> find(const key_t& k);

  /**
   * Dump all bridge_domain-doamin into the stream provided
   */
  static void dump(std::ostream& os);

  /**
   * replay the object to create it in hardware
   */
  void replay(void);

  /**
   * Convert to string for debugging
   */
  std::string to_string() const;

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

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

    /**
     * Handle a replay event
     */
    void handle_replay();

    /**
     * Show the object in the Singular DB
     */
    void show(std::ostream& os);

    /**
     * Get the sortable Id of the listener
     */
    dependency_t order() const;
  };

  /**
   * event_handler to register with OM
   */
  static event_handler m_evh;

  /**
   * Commit the acculmulated changes into VPP. i.e. to a 'HW" write.
   */
  void update(const gbp_contract& obj);

  /**
   * Find or add the instance of the contract domain in the OM
   */
  static std::shared_ptr<gbp_contract> find_or_add(const gbp_contract& temp);

  /*
   * It's the VPPHW class that updates the objects in HW
   */
  friend class OM;

  /**
   * It's the singular_db class that calls replay()
   */
  friend class singular_db<key_t, gbp_contract>;

  /**
   * Sweep/reap the object if still stale
   */
  void sweep(void);

  /**
   * HW configuration for the result of creating the endpoint
   */
  HW::item<uint32_t> m_hw;

  /*
   * The scope of the contract
   */
  scope_t m_scope;

  /**
   * The source EPG ID
   */
  sclass_t m_sclass;

  /**
   * The destination EPG ID
   */
  sclass_t m_dclass;

  /**
   * The ACL applied to traffic between the gourps
   */
  std::shared_ptr<ACL::l3_list> m_acl;

  /**
   * The gbp rules applied to traffic between the gourps
   */
  gbp_rules_t m_gbp_rules;

  /**
   * the set of Ether-types allowed by this contract
   */
  ethertype_set_t m_allowed_ethertypes;

  /**
   * A map of all bridge_domains
   */
  static singular_db<key_t, gbp_contract> m_db;
};

std::ostream& operator<<(std::ostream& os, const gbp_contract::key_t& key);
}; // namespace

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

#endif
