/*******************************************************************************
 * Copyright (c) 2016 CEA LIST.
 *
 * 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
 *
 * Created on: 4 févr. 2015
 *
 * Contributors:
 *  Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
 *   - Initial API and implementation
 ******************************************************************************/

#include "BasicTraceParser.h"

#include <fstream>

#include <fml/expression/ExpressionConstructor.h>

#include <fml/executable/ExecutableQuery.h>
#include <fml/executable/ExecutableSystem.h>
#include <fml/executable/InstanceOfPort.h>

#include <fml/symbol/Symbol.h>

#include <fml/trace/TracePoint.h>
#include <fml/trace/TraceSequence.h>

#include <sew/Configuration.h>


namespace sep
{

////////////////////////////////////////////////////////////////////////////////
// OTHER API
////////////////////////////////////////////////////////////////////////////////

/*
 * Exemple de trace basique
1
TSI_target?1
120
RSD_ENABLED_source!1
0
PSD_ENABLED_source!1
423385
RSD_CMD_source!1
0
PSD_STATE1_target?0
3025646
DEP_AUTH1_source!1
1059822
TSI1_target?0

BASIC#XLIA:
	INPUT  env_connection_signal(  )
	OUTPUT env_enter_pin_message(  )
	INPUT  env_user_pin( 3782 )
	OUTPUT env_asked_withdrawal_message(  )
	INPUT  env_asked_withdrawal( 5001 )
	OUTPUT env_operation_not_possible( 2 , 5000 )
*/

bool BasicTraceParser::parseBasicXliaTrace(TraceSequence & aTraceElement,
		std::ifstream & inFile, const BF & aVarTime)
{
	bool isOK = true;

		//for debug purposes
	bool isOKLine = true;
	int cptLine = 0;

	bfVarTime = aVarTime;

	std::string inLine;

	while( inFile.good() )
	{
		cptLine ++;

		std::getline(inFile, inLine);

		StringTools::ltrim( inLine );

		if( (inLine == "\\n") || inLine.empty() )
		{
			// !!NOTHING: SKIP NEWLINE
			isOKLine = true;
		}
		else if((inLine[0]) == '#')
		{
			// COMMENT
			isOKLine = true;
		}
		else if( StringTools::startsWith(inLine, "delta") )
		{
			isOKLine = parseBasicXliaTraceDuration(aTraceElement, inLine, aVarTime);
		}
		else if( REGEX_STARTS(inLine, "(input|output|INPUT|OUTPUT)") )
		{
			isOKLine = parseBasicXliaTraceSignal(aTraceElement, inLine);
		}

		else if((inLine[0]) == '{')
		{
			isOKLine = parseBasicTraceStructure(aTraceElement, inLine);
		}

		isOK = isOKLine && isOK;

		if(not isOKLine)
		{
			AVM_OS_WARN << "Error: Error while reading trace file on line "
					<< cptLine << ": " << inLine << std::endl;
		}

	}

	return( isOK );
}

bool BasicTraceParser::parseBasicXliaTraceDuration(TraceSequence & aTraceElement,
		const std::string & inLine, const BF & aVarTime)
{

	std::string::size_type pos = inLine.find('=');
	std::string delta = inLine.substr(pos+1);
	StringTools::ltrim( delta );

	avm_integer_t duration;
	if( from_string(delta, duration, std::dec) )
	{
		bfTP = new TracePoint(
				ENUM_TRACE_POINT::TRACE_TIME_NATURE,
				AVM_OPCODE_TIMED_GUARD, NULL,
				aVarTime.to_ptr< InstanceOfData >(),
				ExpressionConstructor::newInteger(duration) );

		aTraceElement.points.append( bfTP );

		return( true );
	}

	return( false );
}


bool BasicTraceParser::parseBasicXliaTraceSignal(
		TraceSequence & aTraceElement, const std::string & inLine)
{
	bfTP = aTracePoint = new TracePoint(ENUM_TRACE_POINT::TRACE_COM_NATURE);

	Modifier::DIRECTION_KIND ioDirection;

	//std::string::size_type pos = inLine.find('?');
	std::string message;

AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	AVM_OS_LOG << "PARSER : the message trace is >>" << inLine << "<<"
			<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )

	if(  REGEX_STARTS(inLine, "(input|INPUT)") )
	{
		ioDirection = Modifier::DIRECTION_INPUT_KIND;
		message = inLine.substr(6);
	}
	else if(  REGEX_STARTS(inLine, "(output|OUTPUT)") )
	{
		ioDirection = Modifier::DIRECTION_OUTPUT_KIND;
		message = inLine.substr(7);
	}

	message = StringTools::trim(message);

AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	AVM_OS_LOG << "PARSER : the message is >>" << message << "<<" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )

	std::string::size_type pos = message.find('(');
	if( pos != std::string::npos )
	{
		ExecutableQuery XQuery( mConfiguration );

		const Symbol & foundSignal =
				XQuery.getPortByQualifiedNameID(
						message.substr(0, pos), ioDirection, false );

AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	AVM_OS_LOG << "PARSER : the port is >>" << message.substr(0, pos) << "<<"
			<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )

		if( foundSignal.valid() )
		{
			InstanceOfPort* port = foundSignal.rawPort();
			aTracePoint->object = port;


			if( ioDirection == Modifier::DIRECTION_INPUT_KIND )
			{
				if( port->hasInputRoutingData() &&
					port->getInputRoutingData().isProtocolENV() )
				{
					aTracePoint->op = AVM_OPCODE_INPUT_ENV;
				}
				else
				{
					aTracePoint->op = AVM_OPCODE_INPUT;
				}

			}
			else if( ioDirection == Modifier::DIRECTION_OUTPUT_KIND )
			{
				if( port->hasOutputRoutingData() &&
					port->getOutputRoutingData().isProtocolENV() )
				{
					aTracePoint->op = AVM_OPCODE_OUTPUT_ENV;
				}
				else
				{
					aTracePoint->op = AVM_OPCODE_OUTPUT;
				}

			}

			//TODO : check what happens if there is no parameter given ()

			if( parseBasicTraceSignalParameters(aTracePoint, port,
					message.substr(pos + 1, message.size()-pos-2)) )
			{
				aTraceElement.points.append( bfTP );

AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	AVM_OS_LOG << "PARSER : and its parameters are >>"
			<< message.substr(pos + 1, message.size()-pos-2) << "<<"
			<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )

				return( true );
			}
		}
	}

	else
	{
		aTracePoint->value = ExpressionConstructor::newString(inLine);

		aTraceElement.points.append( bfTP );
	}

	return( false );
}



bool BasicTraceParser::parseBasicTrace(TraceSequence & aTraceElement,
		std::ifstream & inFile, const BF & aVarTime)
{
	bool isOK = true;

		//for debug purposes
	bool isOKLine = true;
	int cptLine = 0;

	bfVarTime = aVarTime;

	std::string inLine;

	while( inFile.good() )
	{
		cptLine ++;

		std::getline(inFile, inLine);

		StringTools::ltrim( inLine );

		if( (inLine == "\\n") || inLine.empty() )
		{
			// !!NOTHING: SKIP NEWLINE
			isOKLine = true;
		}
		else if((inLine[0]) == '#')
		{
			// COMMENT
			isOKLine = true;
		}
		else if( std::isdigit(inLine[0]) )
		{
			isOKLine = parseBasicTraceDuration(aTraceElement, inLine, aVarTime);
		}
		else if( std::isalpha(inLine[0]) )
		{
			isOKLine = parseBasicTraceSignal(aTraceElement, inLine);
		}

		else if((inLine[0]) == '{')
		{
			isOKLine = parseBasicTraceStructure(aTraceElement, inLine);
		}

		isOK = isOKLine && isOK;

		if(not isOKLine)
		{
			AVM_OS_WARN << "Error: Error while reading trace file on line "
					<< cptLine << std::endl;
		}

	}

	return( isOK );
}



bool BasicTraceParser::parseBasicTraceDuration(TraceSequence & aTraceElement,
		const std::string & inLine, const BF & aVarTime)
{
	avm_integer_t duration;
	if( from_string(inLine, duration, std::dec) )
	{
		bfTP = new TracePoint(
				ENUM_TRACE_POINT::TRACE_TIME_NATURE,
				AVM_OPCODE_TIMED_GUARD, NULL,
				aVarTime.to_ptr< InstanceOfData >(),
				ExpressionConstructor::newInteger(duration) );

		aTraceElement.points.append( bfTP );

		return( true );
	}

	return( false );
}

bool BasicTraceParser::parseBasicTraceSignal(
		TraceSequence & aTraceElement, const std::string & inLine)
{
	bfTP = aTracePoint = new TracePoint(ENUM_TRACE_POINT::TRACE_COM_NATURE);

	Modifier::DIRECTION_KIND io_dir;

	std::string::size_type pos = inLine.find('?');
	if( pos != std::string::npos )
	{
		io_dir = Modifier::DIRECTION_INPUT_KIND;
		aTracePoint->op = AVM_OPCODE_INPUT;
	}
	else if( (pos = inLine.find('!')) != std::string::npos )
	{
		io_dir = Modifier::DIRECTION_OUTPUT_KIND;
		aTracePoint->op = AVM_OPCODE_OUTPUT;
	}

	if( pos != std::string::npos )
	{
		ExecutableQuery XQuery( mConfiguration );

		const Symbol & foundSignal =
				XQuery.getPortByQualifiedNameID(
						inLine.substr(0, pos), io_dir, false );

		if( foundSignal.valid() )
		{
			InstanceOfPort* port = foundSignal.rawPort();
			aTracePoint->object = port;

			if( parseBasicTraceSignalParameters(
					aTracePoint, port,  inLine.substr(pos + 1)))
			{
				aTraceElement.points.append( bfTP );

				return( true );
			}
		}
	}

	else
	{
		aTracePoint->value = ExpressionConstructor::newString(inLine);

		aTraceElement.points.append( bfTP );
	}

	return( false );
}

/*
 * This method takes an inputs:
 * a trace point, a port and a string expression
 *
 */
bool BasicTraceParser::parseBasicTraceSignalParameters(
		TracePoint * aTracePoint, InstanceOfPort* port,
		const std::string & anExpr)
{
	std::string::size_type pos;
	avm_size_t nbParams = port->getParameterCount();
	avm_size_t count = 0;
	//this variables is used to count the number of parameters given in the trace
	std::string currentExpr = anExpr;

	//TODO: do the verification on the number of parameters while parsing
	// e.g. create an array with the parameter values
	while ((pos = currentExpr.find(',') )!= std::string::npos)
	{
		currentExpr = currentExpr.substr(pos+1);
		count++;
	}

	StringTools::trim(currentExpr);
	if( currentExpr.compare("") != 0 )
	{
		count++;
	}

	if( count != port->getParameterCount() )
	{
		// if the number of parameters given in the trace does
		// not match  the declaration in the file specification
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
	AVM_OS_LOG << "PARSER WARNING : the number of parameters expected "
			"is " << nbParams << " while the actual number of parameters "
			"given in the trace is " << count << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , PROCESSOR )
		return false;
	}

	if (nbParams != 0)
	{
		aTracePoint->newArrayValue(nbParams);
		std::string  param;
		currentExpr = anExpr;
		int i = 0;
		bool correct = true;
		//the correct number of parameters has already been ascertained
		while (((pos = currentExpr.find(',')) != std::string::npos) && correct)
		{
			// retrieving parameter from the string
			param = currentExpr.substr(0, pos);
			BF paramBF = parseBasicTraceSignalParameter(
					(* (port->getParameterType(i))), param);

			if(paramBF == NULL)
			{
				return false;
			}
			else
			{
				aTracePoint->val(i, paramBF);
				i++;
				currentExpr = currentExpr.substr(pos+1);
			}
		}
		param = StringTools::trim(currentExpr);
		BF paramBF = parseBasicTraceSignalParameter(* port->getParameterType(i), param);
		//BF paramBF = ExpressionConstructor::newExpr(* port->getParameterType(i), param);
		if(paramBF == NULL)
		{
			return false;
		}
		else
		{
			aTracePoint->val(i, paramBF);
		}
		return true;
	}
	else
	{
		return true;
	}
	return true;
}

/*
 * anExpr is the string representing the parameter to be parsed
 * aTypeSpecifier is the type of the parameter
 * returns a BF representing the parameter
 */
BF BasicTraceParser::parseBasicTraceSignalParameter(
		const ITypeSpecifier & aTypeSpecifier, const std::string & anExpr)
{
	std::string param = anExpr;
	StringTools::trim(param);

	BF paramBF;

//AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
//	AVM_OS_LOG << "PARSER: parameter type: ";
//    aTypeSpecifier.toStream(AVM_OS_LOG);
//	AVM_OS_LOG << std::endl;
//AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )

	// Removing encompassing quotes in strings before building
	if( aTypeSpecifier.isTypedString()
		&& (not param.empty()) && (param[0] == '"') )
	{
		param = param.substr(1, param.size() - 2);

		paramBF = ExpressionConstructor::newString(param);

AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	AVM_OS_LOG << "PARSER: reading a string: " << param << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	}

	else if( aTypeSpecifier.isTypedCharacter() && (not param.empty()) )
	{
		if( param.size() == 1 )
		{
			paramBF = ExpressionConstructor::newChar(param[0]);
		}
		else if( param[0] == '\'' )
		{
			paramBF = ExpressionConstructor::newChar(param[1]);
		}
		else // ERROR !!!
		{
			paramBF = ExpressionConstructor::newChar(param[0]);
		}

AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	AVM_OS_LOG << "PARSER: reading a string: " << param << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	}
	// machines as parameters contain run and pid information,
	// we must remove them (no configuration yet)
	else if( aTypeSpecifier.isTypedMachine() )
	{
		if( StringTools::startsWith(param, "run::") )
		{
			std::string::size_type parampos = param.find(':', 5);
			if( parampos != std::string::npos )
			{
				param = param.substr(parampos+1);
			}

			paramBF = ExpressionConstructor::newExprRuntine(mConfiguration, param);
		}
		else
		{
			paramBF = ExpressionConstructor::newExprMachine(mConfiguration, param);
		}

AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	AVM_OS_LOG << "PARSER: reading a machine: " << param << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	}

	else
	{
		paramBF = ExpressionConstructor::newExpr(
				mConfiguration, aTypeSpecifier, param);
	}

	if( paramBF.invalid() )
	{
		AVM_OS_WARN << "PARSER: failed to build BF from parameter: "
				<< param << std::endl;
	}
	else
	{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	AVM_OS_LOG << "PARSER: parameter value read: " << paramBF << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
	}

	return paramBF;
}


bool BasicTraceParser::parseBasicTraceStructure(
		TraceSequence & aTraceElement, const std::string & inLine)
{
	return( false );
}


} /* namespace sep */
