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

#include "vom/hw.hpp"
#include "vom/hw_cmds.hpp"
#include "vom/logger.hpp"

namespace VOM {
HW::cmd_q::cmd_q()
  : m_enabled(true)
  , m_connected(false)
  , m_conn()
{
}

HW::cmd_q::~cmd_q()
{
}

HW::cmd_q&
HW::cmd_q::operator=(const HW::cmd_q& f)
{
  return (*this);
}

/**
 * Run the connect/dispatch thread.
 */
void
HW::cmd_q::rx_run()
{
  while (m_connected) {
    m_conn.ctx().dispatch();
  }
}

void
HW::cmd_q::enqueue(cmd* c)
{
  std::shared_ptr<cmd> sp(c);

  m_queue.push_back(sp);
}

void
HW::cmd_q::enqueue(std::shared_ptr<cmd> c)
{
  m_queue.push_back(c);
}

void
HW::cmd_q::enqueue(std::queue<cmd*>& cmds)
{
  while (cmds.size()) {
    std::shared_ptr<cmd> sp(cmds.front());

    m_queue.push_back(sp);
    cmds.pop();
  }
}

bool
HW::cmd_q::connect()
{
  int rv;

  if (m_connected)
    return m_connected;

  rv = m_conn.connect();

  m_connected = true;
  m_rx_thread.reset(new std::thread(&HW::cmd_q::rx_run, this));
  return (rv == 0);
}

void
HW::cmd_q::disconnect()
{

  if (!m_connected)
    return;

  m_connected = false;

  if (m_rx_thread && m_rx_thread->joinable()) {
    m_rx_thread->join();
  }

  m_conn.disconnect();
}

void
HW::cmd_q::enable()
{
  m_enabled = true;
}

void
HW::cmd_q::disable()
{
  m_enabled = false;
}

rc_t
HW::cmd_q::write()
{
  rc_t rc = rc_t::OK;

  /*
   * The queue is enabled, Execute each command in the queue.
   * If one execution fails, abort the rest
   */
  auto it = m_queue.begin();

  while (it != m_queue.end()) {
    std::shared_ptr<cmd> c = *it;

    VOM_LOG(log_level_t::DEBUG) << *c;

    if (m_enabled) {
      /*
       * before we issue the command we must move it to the pending
       * store
       * ince a async event can be recieved before the command
       * completes
       */
      rc = c->issue(m_conn);

      if (rc_t::OK == rc) {
        /*
         * move to the next
         */
      } else {
        /*
         * barf out without issuing the rest
         */
        VOM_LOG(log_level_t::ERROR) << "Failed to execute: " << c->to_string();
        break;
      }
    } else {
      /*
       * The HW is disabled, so set each command as succeeded
       */
      c->succeeded();
    }

    ++it;
  }

  /*
   * erase all objects in the queue
   */
  m_queue.erase(m_queue.begin(), m_queue.end());

  return (rc);
}

/*
 * The single Command Queue
 */
HW::cmd_q* HW::m_cmdQ;
HW::item<bool> HW::m_poll_state;

/**
 * Initialse the connection to VPP
 */
void
HW::init(HW::cmd_q* f)
{
  m_cmdQ = f;
}

/**
 * Initialse the connection to VPP
 */
void
HW::init()
{
  m_cmdQ = new cmd_q();
}

void
HW::enqueue(cmd* cmd)
{
  m_cmdQ->enqueue(cmd);
}

void
HW::enqueue(std::shared_ptr<cmd> cmd)
{
  m_cmdQ->enqueue(cmd);
}

void
HW::enqueue(std::queue<cmd*>& cmds)
{
  m_cmdQ->enqueue(cmds);
}

bool
HW::connect()
{
  return m_cmdQ->connect();
}

void
HW::disconnect()
{
  m_cmdQ->disconnect();
}

void
HW::enable()
{
  m_cmdQ->enable();
}

void
HW::disable()
{
  m_cmdQ->disable();
}

rc_t
HW::write()
{
  return (m_cmdQ->write());
}

bool
HW::poll()
{
  std::shared_ptr<cmd> poll(new hw_cmds::poll(m_poll_state));

  HW::enqueue(poll);
  HW::write();

  return (m_poll_state);
}

template <>
std::string
HW::item<bool>::to_string() const
{
  std::ostringstream os;

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

template <>
std::string
HW::item<unsigned int>::to_string() const
{
  std::ostringstream os;

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

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