/*******************************************************************************
 * Copyright (c) 2017 fortiss GmbH
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Jose Cabral - initial API and implementation and/or initial documentation
 *******************************************************************************/

#include "processinterface.h"
#include <string>
#include <sstream>
#include <vector>
#include <criticalregion.h>

#include <umic_dio.h>
#include <umic_relay.h>
#include <umic_led.h>

const std::string CUMICProcessInterface::scmDIOID("dio");
#if UMIC_LED_ENABLED
const std::string CUMICProcessInterface::scmLEDID("led");
#endif
#if UMIC_RELAY_ENABLED
const std::string CUMICProcessInterface::scmRELAYID("relay");
#endif
bool CUMICProcessInterface::smDIOInitialized = false;
uint8_t CUMICProcessInterface::smIODirections = 0;
CSyncObject CUMICProcessInterface::directionsMutex = CSyncObject();

const char * const CUMICProcessInterface::scmOK = "OK";
const char * const CUMICProcessInterface::scmPinInUse = "Pin already in use by other FB";
const char * const CUMICProcessInterface::scmNotInitialised = "FB not initialized";
const char * const CUMICProcessInterface::scmError = "Error";
const char * const CUMICProcessInterface::scmCouldNotRead = "Could not read";
const char * const CUMICProcessInterface::scmCouldNotWrite = "Could not write";

CUMICProcessInterface::CUMICProcessInterface(CResource *paSrcRes, const SFBInterfaceSpec *paInterfaceSpec, const CStringDictionary::TStringId paInstanceNameId, TForteByte *paFBConnData, TForteByte *paFBVarsData) :
    CProcessInterfaceBase(paSrcRes, paInterfaceSpec, paInstanceNameId, paFBConnData, paFBVarsData), mIOType(UNDEFINED), mNumber(0){
}

CUMICProcessInterface::~CUMICProcessInterface(){
    deinitialise();
}

bool CUMICProcessInterface::initialise(bool paIsInput){

  bool retVal = false;
  std::stringstream streamBuf(std::string(PARAMS().getValue()));
  std::string segment;
  std::vector<std::string> paramsList;
  unsigned int number;

  while(std::getline(streamBuf, segment, '.')){ //separate the PARAMS input by '.' for easier processing
    paramsList.pushBack(segment);
  }

  STATUS() = scmNotInitialised;

  if(2 == paramsList.size()){ //TYPE.NUMBER
    std::string ioType = paramsList[0];

    std::stringstream ss(paramsList[1]);
    ss >> number;

    if(scmDIOID == ioType){
      bool statusCorrect = true;
      if(!CUMICProcessInterface::smDIOInitialized){
        DEVLOG_INFO("Global Initializing Digital I/O\n");
        if(0 > umic_dio_init()){
          statusCorrect = false;
          DEVLOG_ERROR("Global Initialization of Digital I/O FAILED!\n");
        }
        else{
          DEVLOG_INFO("Global Initialization of Digital I/O SUCCEED!\n");
        }
      }
      if(statusCorrect && 8 >= number && 0 != number){
        CCriticalRegion(CUMICProcessInterface::directionsMutex);
        uint8_t currentDirection;
        if(paIsInput){ // 0 for input
          currentDirection = static_cast<uint8_t>(CUMICProcessInterface::smIODirections & ~(1 << (number - 1)));
        }
        else{ //1 for output
          currentDirection = static_cast<uint8_t>(CUMICProcessInterface::smIODirections | (1 << (number - 1)));
        }
        if(0 > umic_dio_set_direction(0, currentDirection)){
          DEVLOG_ERROR("Initializing Digital I/O FAILED!");
        }
        else{
          CUMICProcessInterface::smIODirections = currentDirection;
          mIOType = DIO;
          retVal = true;
        }
      }
    }
#if UMIC_LED_ENABLED
    else  if(scmLEDID == ioType && !paIsInput){
      if(7 >= number){
        retVal = true;
        mIOType = LED;
      }
    }
#endif
#if UMIC_RELAY_ENABLED
    else if(scmRELAYID == ioType && !paIsInput){
      if(2 >= number && 0 != number){
        retVal = true;
        mIOType = RELAY;
      }
    }
#endif
  }

  if(true == retVal){
    STATUS() = scmOK;
    mNumber = static_cast<uint8_t>(number);
  }
  else{
    DEVLOG_ERROR("The FB with PARAMS() = '%s' couldn't be initialized. PARAMS is not well defined.\n", PARAMS().getValue());
  }
  return retVal;
}

bool CUMICProcessInterface::deinitialise(){
  //TODO: The global initialization umic_dio_init doesn't have its counterpart umic_dio_release
  mNumber = 0;
  return true;
}

bool CUMICProcessInterface::readPin(){
  bool retVal = false;
  if(DIO == mIOType){
    int32_t currentValue = umic_dio_get_input(0);
    if (0 > currentValue){
      DEVLOG_ERROR("Error reading PIN %d\n", mNumber);
      STATUS() = scmCouldNotRead;
    }else{
      IN_X() = ( (currentValue) & (1 << (mNumber - 1)) ) ? true : false;
      STATUS() = scmOK;
      retVal = true;
    }
  }else{
    STATUS() = scmNotInitialised;
  }
  return retVal;
}

bool CUMICProcessInterface::writePin(){
  bool retVal = false;
  if(UNDEFINED != mIOType){
    if(DIO == mIOType){
      int32_t currentValue = umic_dio_get_input(0);
      if(0 > currentValue){
        DEVLOG_ERROR("Error reading PIN to later write on it%d\n", mNumber);
        STATUS() = scmCouldNotRead;
      }
      else{
        if(false != OUT_X()){
          currentValue |= 1 << (mNumber - 1); //set bit
        }
        else{
          currentValue &= ~(1 << (mNumber - 1)); //clear bit
        }
        if(0 > umic_dio_set_output(0, static_cast<uint8_t>(currentValue))){
          DEVLOG_ERROR("Error writing IO%d\n", mNumber);
          STATUS() = scmCouldNotWrite;
        }
        else{
          STATUS() = scmOK;
          retVal = true;
        }
      }
    }
#if UMIC_LED_ENABLED
    else if(LED == mIOType){
      int32_t res;
      if(false != OUT_X()){
        res = umic_led_set(mNumber);
      }
      else{
        res = umic_led_clr(mNumber);
      }
      if(0 > res){
        DEVLOG_ERROR("Error writing LED%d\n", mNumber);
        STATUS() = scmCouldNotWrite;
      }
      else{
        STATUS() = scmOK;
        retVal = true;
      }
    }
#endif
#if UMIC_LED_ENABLED
    else if(RELAY == mIOType){
      int32_t res;
      if(false != OUT_X()){
        res = umic_relay_on(static_cast<uint8_t>(mNumber - 1));
      }
      else{
        res = umic_relay_off(static_cast<uint8_t>(mNumber - 1));
      }
      if(0 > res){
        DEVLOG_ERROR("Error writing RELAY%d\n", mNumber);
        STATUS() = scmCouldNotWrite;
      }
      else{
        STATUS() = scmOK;
        retVal = true;
      }
    }
#endif
  }
  else{
    STATUS() = scmNotInitialised;
  }
  return retVal;
}
