/*
 * 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_HW_H__
#define __VOM_HW_H__

#include <deque>
#include <map>
#include <queue>
#include <sstream>
#include <string>
#include <thread>

#include "vom/cmd.hpp"
#include "vom/connection.hpp"
#include "vom/types.hpp"

namespace VOM {

class cmd;
class HW
{
public:
  /**
   * A HW::item is data that is either to be written to or read from
   * VPP/HW.
   * The item is a pair of the data written/read and the result of that
   * operation.
   */
  template <typename T>
  class item
  {
  public:
    /**
     * Constructor
     */
    item(const T& data)
      : item_data(data)
      , item_rc(rc_t::NOOP)
    {
    }
    /**
     * Constructor
     */
    item()
      : item_data()
      , item_rc(rc_t::UNSET)
    {
    }

    /**
     * Constructor
     */
    item(rc_t rc)
      : item_data()
      , item_rc(rc)
    {
    }

    /**
     * Constructor
     */
    item(const T& data, rc_t rc)
      : item_data(data)
      , item_rc(rc)
    {
    }

    /**
     * Destructor
     */
    ~item() = default;

    /**
     * Comparison operator
     */
    bool operator==(const item<T>& i) const
    {
      return (item_data == i.item_data);
    }

    /**
     * Copy assignment
     */
    item& operator=(const item& other)
    {
      item_data = other.item_data;
      item_rc = other.item_rc;

      return (*this);
    }

    /**
     * Return the data read/written
     */
    T& data() { return (item_data); }

    /**
     * Const reference to the data
     */
    const T& data() const { return (item_data); }

    /**
     * Get the HW return code
     */
    rc_t rc() const { return (item_rc); }

    /**
     * Set the HW return code - should only be called from the
     * family of Command objects
     */
    void set(const rc_t& rc) { item_rc = rc; }

    /**
     * Return true if the HW item is configred in HW
     */
    operator bool() const { return (rc_t::OK == item_rc); }

    /**
     * update the item to the desired state.
     *  return true if a HW update is required
     */
    bool update(const item& desired)
    {
      bool need_hw_update = false;

      /*
       * if the deisred set is unset (i.e. defaulted, we've
       * no update to make
       */
      if (rc_t::UNSET == desired.rc()) {
        return (false);
      }
      /*
       * A HW update is needed if thestate is different
       * or the state is not yet in HW
       */
      need_hw_update = (item_data != desired.data() || rc_t::OK != rc());

      item_data = desired.data();

      return (need_hw_update);
    }

    /**
     * convert to string format for debug purposes
     */
    std::string to_string() const
    {
      std::ostringstream os;

      os << "hw-item:["
         << "rc:" << item_rc.to_string() << " data:" << item_data.to_string()
         << "]";

      return (os.str());
    }

  private:
    /**
     * The data
     */
    T item_data;

    /**
     * The result when the item was written
     */
    rc_t item_rc;
  };

  /**
   * The pipe to VPP into which we write the commands
   */
  class cmd_q
  {
  public:
    /**
     * Constructor
     */
    cmd_q();
    /**
     * Destructor
     */
    ~cmd_q();

    /**
     * Copy assignement - only used in UT
     */
    cmd_q& operator=(const cmd_q& f);

    /**
     * Enqueue a command into the Q.
     */
    virtual void enqueue(cmd* c);
    /**
     * Enqueue a command into the Q.
     */
    virtual void enqueue(std::shared_ptr<cmd> c);

    /**
     * Enqueue a set of commands
     */
    virtual void enqueue(std::queue<cmd*>& c);

    /**
     * Write all the commands to HW
     */
    virtual rc_t write();

    /**
     * Blocking Connect to VPP - call once at bootup
     */
    virtual void connect();

    /**
     * Disable the passing of commands to VPP. Whilst disabled all
     * writes will be discarded. Use this during the reset phase.
     */
    void disable();

    /**
     * Enable the passing of commands to VPP - undoes the disable.
     * The Q is enabled by default.
     */
    void enable();

  private:
    /**
     * A queue of enqueued commands, ready to be written
     */
    std::deque<std::shared_ptr<cmd>> m_queue;

    /**
     * A map of issued, but uncompleted, commands.
     *  i.e. those that we are waiting, async stylee,
     * for VPP to complete
     */
    std::map<cmd*, std::shared_ptr<cmd>> m_pending;

    /**
     * VPP Q poll function
     */
    void rx_run();

    /**
     * The thread object running the poll/dispatch/connect thread
     */
    std::unique_ptr<std::thread> m_rx_thread;

    /**
     * A flag indicating the client has disabled the cmd Q.
     */
    bool m_enabled;

    /**
     * A flag for the thread to poll to see if the queue is still alive
     */
    bool m_connected;

    /**
     * The connection to VPP
     */
    connection m_conn;
  };

  /**
   * Initialise the HW connection to VPP - the UT version passing
   * a mock Q.
   */
  static void init(cmd_q* f);

  /**
   * Initialise the HW
   */
  static void init();

  /**
   * Enqueue A command for execution
   */
  static void enqueue(cmd* f);

  /**
   * Enqueue A command for execution
   */
  static void enqueue(std::shared_ptr<cmd> c);

  /**
   * Enqueue A set of commands for execution
   */
  static void enqueue(std::queue<cmd*>& c);

  /**
   * Write/Execute all commands hitherto enqueued.
   */
  static rc_t write();

  /**
   * Blocking Connect to VPP
   */
  static void connect();

  /**
   * Blocking pool of the HW connection
   */
  static bool poll();

private:
  /**
   * The command Q toward HW
   */
  static cmd_q* m_cmdQ;

  /**
   * HW::item representing the connection state as determined by polling
   */
  static HW::item<bool> m_poll_state;

  /**
   * Disable the passing of commands to VPP. Whilst disabled all writes
   * will be discarded. Use this during the reset phase.
   */
  static void disable();

  /**
   * Enable the passing of commands to VPP - undoes the disable.
   * The Q is enabled by default.
   */
  static void enable();

  /**
   * Only the OM can enable/disable HW
   */
  friend class OM;
};

/**
 * bool Specialisation for HW::item to_string
 */
template <>
std::string HW::item<bool>::to_string() const;

/**
 * uint Specialisation for HW::item to_string
 */
template <>
std::string HW::item<unsigned int>::to_string() const;
};

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

#endif
