/*******************************************************************************
 * Copyright (c) 2012 -2014 AIT, fortiss GmbH
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Filip Andren, Alois Zoitl - initial API and implementation and/or initial documentation
 *******************************************************************************/
#include "opcconnection.h"
#include "opcconnectionimpl.h"
#include "opceventhandler.h"
#include "opcprocessvar.h"
#include "Cmd_AddConnection.h"
#include "Cmd_AddOPCProcessVar.h"
#include "Cmd_SetProcessVarValue.h"

using namespace forte::com_infra;

COpcConnection::COpcConnection(const char *pa_acHost, const char *pa_acServerName, COpcEventHandler* pa_eventHandler) :
    m_nGroupCount(0), m_eConnectionEvent(e_Disconnected), m_acHost(pa_acHost), m_acServerName(pa_acServerName), m_acGroupName(0), m_nReqUpdateRate(0), m_nRealUpdateRate(0), m_nDeadBand(0), m_bIsConnected(false), m_bBlockingConnect(false),
   m_eventHandler(pa_eventHandler){
  m_pOpcConnectionImpl = new COpcConnectionImpl(pa_acHost, pa_acServerName, this);
}

COpcConnection::~COpcConnection(){
  delete m_pOpcConnectionImpl;
}

void COpcConnection::addGroup(const char* pa_acGroupName, unsigned long pa_nReqUpdateRate, float pa_nDeadBand, CComLayer* pa_pComCallback){
  m_oSync.lock();
  m_lOpcGroupMapList.pushBack(new SOpcGroupMap(pa_acGroupName, m_eventHandler->addComCallback(pa_pComCallback)));
  m_oSync.unlock();

  m_pOpcConnectionImpl->addGroup(pa_acGroupName, pa_nReqUpdateRate, pa_nDeadBand);

  m_nGroupCount++;
}

void COpcConnection::removeGroup(const char* pa_acGroupName){
  m_oSync.lock();
  TOpcGroupMapList::Iterator itDelete = m_lOpcGroupMapList.begin();
  TOpcGroupMapList::Iterator it_group = m_lOpcGroupMapList.begin();
  TOpcGroupMapList::Iterator itEnd_group = m_lOpcGroupMapList.end();

  if(it_group != itEnd_group){
    if(strcmp(it_group->m_acGroupName, pa_acGroupName) == 0){
      m_lOpcGroupMapList.popFront();
      m_nGroupCount--;
      m_oSync.unlock();
      return;
    }
    ++it_group;
    while(it_group != itEnd_group){
      if(strcmp(it_group->m_acGroupName, pa_acGroupName) == 0){
        m_lOpcGroupMapList.eraseAfter(itDelete);
        m_nGroupCount--;
        m_oSync.unlock();
        return;
      }

      ++itDelete;
      ++it_group;
    }
  }

  m_oSync.unlock();
}

int COpcConnection::send_connect(){
  switch (m_eConnectionEvent){
    case e_Disconnected:
      m_eConnectionEvent = e_Connecting;
      m_eventHandler->sendCommand(new CCmd_AddConnection(m_pOpcConnectionImpl));
      return 0;
    case e_Connecting:
      return 0;
    default: // all other connection states
      return 1;
  }
}

int COpcConnection::send_connect(bool pa_bBlocking){
  m_bBlockingConnect = pa_bBlocking;
  if(pa_bBlocking && !m_bIsConnected){
    m_pOpcConnectionImpl->connect();
    return 1;
  }

  return send_connect();
}

int COpcConnection::send_addItem(COpcProcessVar* pa_pNewItem){
  m_oSync.lock();
  TOpcGroupMapList::Iterator itEnd_group = m_lOpcGroupMapList.end();
  for(TOpcGroupMapList::Iterator it_group = m_lOpcGroupMapList.begin(); it_group != itEnd_group; ++it_group){
    if(strcmp(it_group->m_acGroupName, pa_pNewItem->getItemGroupName()) == 0){
      if(pa_pNewItem->getItemFunction() == COpcProcessVar::e_FBOutput){

        //check if item already added
        TItemDataList::Iterator itEnd_item = (*it_group)->m_lReadItemsList.end();
        for(TItemDataList::Iterator it_item = (*it_group)->m_lReadItemsList.begin(); it_item != itEnd_item; ++it_item){
          if(strcmp(it_item->m_acItemName, pa_pNewItem->getItemName()) == 0){
            m_oSync.unlock();
            return 1;
          }
        }

        it_group->m_lReadItemsList.pushBack(new SOpcItemData(pa_pNewItem->getItemName()));
        break;

      }
      else if(pa_pNewItem->getItemFunction() == COpcProcessVar::e_FBInput){
        //check if item already added
        TItemDataList::Iterator itEnd_item = (*it_group)->m_lWriteItemsList.end();
        for(TItemDataList::Iterator it_item = (*it_group)->m_lWriteItemsList.begin(); it_item != itEnd_item; ++it_item){
          if(strcmp(it_item->m_acItemName, pa_pNewItem->getItemName()) == 0){
            m_oSync.unlock();
            return 1;
          }
        }

        it_group->m_lWriteItemsList.pushBack(new SOpcItemData(pa_pNewItem->getItemName()));
        break;

      }
    }
  }
  m_oSync.unlock();

  if(m_eConnectionEvent == e_Connected){
    m_eventHandler->sendCommand(new CCmd_AddOPCProcessVar(m_pOpcConnectionImpl, pa_pNewItem));

    return 0;
  }

  return -1;
}

int COpcConnection::send_sendItemData(COpcProcessVar* pa_pItem){
  if(pa_pItem->getIsActive()) {
    m_eventHandler->sendCommand(new CCmd_SetProcessVarValue(pa_pItem));
  }
  return 0;
}

void COpcConnection::response_connect(bool pa_bConnectionState){
  m_bIsConnected = pa_bConnectionState;
  if(pa_bConnectionState) {
    m_eConnectionEvent = e_Connected;
  } else {
    m_eConnectionEvent = e_ConnectionFailed;
  }
    //m_eConnectionEvent = e_Disconnected;

  if(!m_bBlockingConnect){
    m_oSync.lock();

    TOpcGroupMapList::Iterator itEnd = m_lOpcGroupMapList.end();
    for(TOpcGroupMapList::Iterator it = m_lOpcGroupMapList.begin(); it != itEnd; ++it){
      m_eventHandler->executeComCallback((*it)->m_nCallbackDesc);
    }

    m_oSync.unlock();
  }
}

void COpcConnection::response_dataReceived(const char *pa_acGroupName, TItemDataList & pa_lItemDataList){
  // Loop through OpcGroups
  m_oSync.lock();
  TOpcGroupMapList::Iterator itEnd_group = m_lOpcGroupMapList.end();
  for(TOpcGroupMapList::Iterator it_group = m_lOpcGroupMapList.begin(); it_group != itEnd_group; ++it_group){

    if(strcmp(it_group->m_acGroupName, pa_acGroupName) == 0){

      // Loop through OpcItems in OpcGroup
      TItemDataList::Iterator itEnd_item = (*it_group)->m_lReadItemsList.end();
      for(TItemDataList::Iterator it_item = (*it_group)->m_lReadItemsList.begin(); it_item != itEnd_item; ++it_item){

        // Loop through OpcItems in ItemDataList
        TItemDataList::Iterator itEnd_newItem = pa_lItemDataList.end();
        TItemDataList::Iterator itErase = pa_lItemDataList.begin();
        for(TItemDataList::Iterator it_newItem = pa_lItemDataList.begin(); it_newItem != itEnd_newItem; ++it_newItem){

          if(strcmp(it_newItem->m_acItemName, it_item->m_acItemName) == 0){
            it_item->m_oItemData = it_newItem->m_oItemData;

            if(it_newItem == pa_lItemDataList.begin()) {
              pa_lItemDataList.popFront();
            } else {
              pa_lItemDataList.eraseAfter(itErase);
            }

            break;
          }

          if(it_newItem != pa_lItemDataList.begin()) {
            ++itErase;
          }
        }
          if(pa_lItemDataList.isEmpty()) {
            break;
          }
      }

      // Change state
      m_eConnectionEvent = e_DataReceived;

      // Notify Com Layer
      m_eventHandler->executeComCallback(it_group->m_nCallbackDesc);
      break;
    }
  }
  m_oSync.unlock();
}

void COpcConnection::response_itemAdded(COpcProcessVar* pa_pOpcItem){
  // Loop through OpcGroups
  m_oSync.lock();
  TOpcGroupMapList::Iterator itEnd_group = m_lOpcGroupMapList.end();
  for(TOpcGroupMapList::Iterator it_group = m_lOpcGroupMapList.begin(); it_group != itEnd_group; ++it_group){
    if(strcmp(it_group->m_acGroupName, pa_pOpcItem->getItemGroupName()) == 0){
      // Change state
      if (pa_pOpcItem->getIsActive()) {
        m_eConnectionEvent = e_ItemAddedOk;
      } else {
        m_eConnectionEvent = e_ItemAddedFailed;
      }
      // Notify Com Layer
      m_eventHandler->executeComCallback(it_group->m_nCallbackDesc);
      break;
    }
  }
  m_oSync.unlock();
}

int COpcConnection::receiveData(const char* pa_acGroupName, TOpcProcessVarList * pa_lOpcProcessVarList){
  int nrData = 0;
  // TODO Case when lists do not match in size

  m_oSync.lock();
  TOpcGroupMapList::Iterator itEnd_group = m_lOpcGroupMapList.end();
  for(TOpcGroupMapList::Iterator it_group = m_lOpcGroupMapList.begin(); it_group != itEnd_group; ++it_group){

    if(strcmp(it_group->m_acGroupName, pa_acGroupName) == 0){

      TItemDataList::Iterator itEnd_item = it_group->m_lReadItemsList.end();
      TItemDataList::Iterator it_item = it_group->m_lReadItemsList.begin();

      TOpcProcessVarList::Iterator itEnd_procVar = pa_lOpcProcessVarList->end();
      TOpcProcessVarList::Iterator it_procVar = pa_lOpcProcessVarList->begin();

      while(it_procVar != itEnd_procVar && it_item != itEnd_item){

        it_procVar->setNewValue(it_item->m_oItemData);

        nrData++;

        ++it_procVar;
        ++it_item;
      }

      break;
    }

  }
  m_oSync.unlock();
  return nrData;
}

