/*******************************************************************************
 * Copyright (c) 2010 - 2014 ACIN, Profactor GmbH, 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:
 *   Alois Zoitl, Gerhard Ebenhofer, Ingo Hegny
 *    - initial API and implementation and/or initial documentation
 *******************************************************************************/
#include <sockhand.h>      //needs to be first pulls in the platform specific includes
#include "fdselecthand.h"
#include "devlog.h"
#include "../core/devexec.h"
#include "../core/cominfra/commfb.h"
#include "../core/cominfra/comCallback.h"
#include "../core/utils/criticalregion.h"

DEFINE_HANDLER(CFDSelectHandler)
CFDSelectHandler::CFDSelectHandler(CDeviceExecution& paDeviceExecution) : CExternalEventHandler(paDeviceExecution)  {
  mConnectionListChanged = false;
#ifdef WIN32
  // Windows Socket Startupcode
  WORD wVersionRequested;
  WSADATA wsaData;

  /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
  wVersionRequested = MAKEWORD(2, 2);

  WSAStartup(wVersionRequested, &wsaData);
#endif
}

CFDSelectHandler::~CFDSelectHandler(){
  this->end();
#ifdef WIN32
  WSACleanup();
#endif
}

// single-threaded-network-code
void CFDSelectHandler::run(){

  struct timeval tv;
  fd_set anFDSet;
  fd_set anFDSetMaster;

  TFileDescriptor nHighestFDID = scmInvalidFileDescriptor;
  int retval = 0;

  FD_ZERO(&anFDSetMaster);

  while(isAlive()){
    // TODO: create method to prevent 100ms timeout on reconnection
    mSync.lock();
    if(true == mConnectionListChanged){
      nHighestFDID = createFDSet(&anFDSetMaster);
    }
    anFDSet = anFDSetMaster;
    mSync.unlock();

    tv.tv_sec = 1; //TODO : To be set!
    tv.tv_usec = 0;

    if(scmInvalidFileDescriptor != nHighestFDID){
      retval = select(static_cast<int>(nHighestFDID + 1), &anFDSet, nullptr, nullptr, &tv);
      if(!isAlive()){
        //the thread has been closed in the meantime do not process any messages anymore
        return;
      }
    }
    else{
      retval = 0;
    }

    if(retval > 0){
      mSync.lock();
      TConnectionContainer::Iterator itEnd(mConnectionsList.end());
      for(TConnectionContainer::Iterator itRunner = mConnectionsList.begin(); itRunner != itEnd;){
        // need to retrieve the callee as the iterator may get invalid in the recvDat function below in case of connection closing
        forte::com_infra::CComCallback *callee = itRunner->mCallee;
        TFileDescriptor sockDes = itRunner->mSockDes;
        ++itRunner;

        if((0 != FD_ISSET(sockDes, &anFDSet)) && (nullptr != callee)){
          mSync.unlock();
          if(forte::com_infra::e_Nothing != callee->recvData(&sockDes,0)){
            startNewEventChain(callee->getCommFB());
          }
          mSync.lock();
        }
      }
      mSync.unlock();
    }
    else{
      if(retval != 0) {
#ifdef WIN32
        DEVLOG_ERROR("Select failed: %d", WSAGetLastError());
#else
        DEVLOG_ERROR("Select failed: %s", strerror(errno));
#endif
      }
    }
  }
}

void CFDSelectHandler::addComCallback(TFileDescriptor paFD, forte::com_infra::CComCallback *paComCallback){
  {
    CCriticalRegion criticalRegion(mSync);
    TConnContType stNewNode = { paFD, paComCallback };
    mConnectionsList.pushBack(stNewNode);
    mConnectionListChanged = true;
  }
  if(!isAlive()){
    this->start();
  }
}

void CFDSelectHandler::removeComCallback(TFileDescriptor paFD){
  CCriticalRegion criticalRegion(mSync);

  TConnectionContainer::Iterator itRunner(mConnectionsList.begin());
  TConnectionContainer::Iterator itRefNode(mConnectionsList.end());
  TConnectionContainer::Iterator itEnd(mConnectionsList.end());

  while(itRunner != itEnd){
    if(itRunner->mSockDes == paFD){
      if(itRefNode ==itEnd){
        mConnectionsList.popFront();
      }
      else{
        mConnectionsList.eraseAfter(itRefNode);
      }
      break;
    }

    itRefNode = itRunner;
    ++itRunner;
  }

  mConnectionListChanged = true;
}

CFDSelectHandler::TFileDescriptor CFDSelectHandler::createFDSet(fd_set *mFDSet){
  TFileDescriptor nRetVal = scmInvalidFileDescriptor;
  FD_ZERO(mFDSet);
  TConnectionContainer::Iterator itEnd(mConnectionsList.end());
  for(TConnectionContainer::Iterator itRunner = mConnectionsList.begin(); itRunner != itEnd; ++itRunner){
    FD_SET(itRunner->mSockDes, mFDSet);
    if(itRunner->mSockDes > nRetVal || scmInvalidFileDescriptor == nRetVal){
      nRetVal = itRunner->mSockDes;
    }
  }
  mConnectionListChanged = false;
  return nRetVal;
}
