/*******************************************************************************
 * Copyright (c) 2005, 2008 Intel Corporation.
 * 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:
 *    Andy Kaylor, Intel - Initial re-implementation of Agent Controller
 * 
 * $Id: ConfigurationManager.c,v 1.22 2008/11/13 20:00:47 jkubasta Exp $
 *******************************************************************************/ 

#include "ConfigurationManager.h"
#include "ConnectionManager.h"
#include "AgentManager.h"
#include <string.h>
#include <stdlib.h>

tptp_int32 configurationManager_init( ConfigurationManager_t* cm )
{
	BZERO( &cm->configData, sizeof(AC_Config_t) );

	strcpy( cm->configDir, ".." );
	strcat( cm->configDir, RELATIVE_CONFIGURATION_DIR );

	/* TODO: Initialize the lists in the configData */


	return 0;
}

tptp_int32 configurationManager_cleanup( ConfigurationManager_t* cm )
{
	/* TODO: Free things allocated during configuration */

	return 0;
}

tptp_int32 configurationManager_setConfigDirectory( ConfigurationManager_t* cm, char *dir )
{
	strcpy( cm->configDir, dir );
	return 0;
}

tptp_int32 configurationManager_readConfigFile( ConfigurationManager_t* cm )
{
	tptp_int32   ret;
	tptp_string* pmt;
	char  configFile[_MAX_PATH];
	tptp_node_t* node;

	strcpy( configFile, cm->configDir );
	strcat( configFile, SERVICE_CONFIG_FILE_NAME );

	/* Read the configuration */
	ret = loadTPTPConfig( configFile, &cm->configData, TRUE );
	if ( ret != 0 )
	{
		/* TODO: Log an error */
		//printf("Error: Failed to load configuration file \"%s\"\n", (configFile?configFile:"null"));
		return ret;
	}

	loggingService_setLogDirectory( cm->loggingService, cm->configData.loggingDirectory );
	loggingService_setLoggingLevel( cm->loggingService, cm->configData.loggingLevel );
	loggingService_setLoggingFormat( cm->loggingService, cm->configData.loggingFormat );

	/* Tell the Agent Manager about the agents we found */
	agentManager_setAvailableAgentList( cm->agentManager, &(cm->configData.agentList) );

    /* Tell the Agent Manager about the global options */
    agentManager_setGlobalOptions( cm->agentManager, &(cm->configData.options) );

	/* Load the message pipelines we found in the configuration file */
	if (cm->configData.msgPipelineList.head == NULL)
	{
		/* TODO: Log an error */
		/* Cannot continue since we did not get any transport layer info from the config file. */
		return -1;
	}

	//243646
	ret = configurationManager_getPeerConnectionTransport(cm, &pmt );
	if ( ( ret != 0 ) || (pmt == NULL) )
	{
		return -1;
	}

	for ( node = cm->configData.msgPipelineList.head; node != NULL; node = node->next )
	{
		message_pipeline_config_t* mpc = (message_pipeline_config_t*)node->data;

		connectionManager_createMessagePipeline( cm->connectionManager,
		                                         mpc->transportLayerLib,
												 mpc->transportType,
			                                     mpc->transportLayerConfig,
				                                 mpc->commandExtractorLib );
	}

	/* Assuming the configuration information specifies a peer connection TL, initialize it */
	if ( cm->configData.peerConnectionTransport != NULL )
	{
		connectionManager_initializePeerConnectionTransport( cm->connectionManager, cm->configData.peerConnectionTransport );
	}

	if ( ( cm->configData.procCntlrAgent ) && (strlen(cm->configData.procCntlrAgent) > 0) )
	{
		agentManager_setDefaultProcessController( cm->agentManager, cm->configData.procCntlrAgent );
	}
	else
	{
		/* TODO: Log an error */
		/* Cannot continue since we did not get the name of the process launcher from the config file. */
		return -1;
	}

	return 0;
}

tptp_int32 configurationManager_getApplicationAliases( ConfigurationManager_t* cm, tptp_string** aliases )
{
	*aliases = cm->configData.applicationAliases;
	return 0;
}

tptp_int32 configurationManager_getPeerConnectionTransport( ConfigurationManager_t* cm, tptp_string** pmt )
{
	if ( pmt == NULL )
	{
		return TPTP_UNEXPECTED_NULL_ARG;
	}

	if ( cm->configData.peerConnectionTransport == NULL )
	{
		return TPTP_AM_NO_PM_TRANSPORT;
	}

	*pmt = tptp_malloc( strlen(cm->configData.peerConnectionTransport)+1 );
	if ( *pmt == NULL )
	{
		return TPTP_SYS_NO_MEM;
	}

	strcpy( *pmt, cm->configData.peerConnectionTransport );

	return 0;
}

/* Bug 175696 starts */
BOOL isEnvironmentValid() {
	BOOL isValid = TRUE;

	/*
	 * Check #1: verify if the environment variable TEMP is pointing to a valid directory
	 */
#if defined(_WIN32) || defined(_WIN64)
	/* Windows */
	HANDLE hFile;
	int rc;
	char *value = malloc(sizeof(char) * MAX_PATH); /* MAX_PATH = 32767 */

	ZeroMemory(value, MAX_PATH);
	rc = GetEnvironmentVariable("TEMP", value, MAX_PATH);

	hFile = CreateFile(value,
		GENERIC_READ,
		FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS,
		NULL);

	if(hFile == INVALID_HANDLE_VALUE) {
		isValid = FALSE;
	}
	else {
		CloseHandle(hFile);
	}

	free(value);
#else
	/* Linux */
	DIR *dir;
	char *value;

	value = getenv("TEMP");
	if(value == NULL) {
		isValid = FALSE;
	}
	else {
		dir = opendir(value);
		if(dir == NULL) {
			isValid = FALSE;
		}
		else {
			closedir(dir);
		}
	}
#endif

	return isValid;
}
/* Bug 175696 ends */
