/*
 * 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 bool connect();

    /**
     * Disconnect to VPP
     */
    virtual void disconnect();

    /**
     * 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 bool connect();

  /**
   * Disconnect to VPP
   */
  static void disconnect();

  /**
   * 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
