/*
 * FreeRTOS+TCP V2.0.3
 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://aws.amazon.com/freertos
 * http://www.FreeRTOS.org
 */


/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"

/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_TCP_server.h"
#include "FreeRTOS_server_private.h"

/* Remove the entire file if TCP is not being used. */
#if( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) )

#if !defined( ARRAY_SIZE )
	#define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] )
#endif


static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket );
static char *strnew( const char *pcString );
/* Remove slashes at the end of a path. */
static void prvRemoveSlash( char *pcDir );

TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount )
{
TCPServer_t *pxServer;
SocketSet_t xSocketSet;

	/* Create a new server.
	xPort / xPortAlt : Make the service available on 1 or 2 public port numbers. */
	xSocketSet = FreeRTOS_CreateSocketSet();

	if( xSocketSet != NULL )
	{
	BaseType_t xSize;

		xSize = sizeof( *pxServer ) - sizeof( pxServer->xServers ) + xCount * sizeof( pxServer->xServers[ 0 ] );

		pxServer = ( TCPServer_t * ) pvPortMallocLarge( xSize );
		if( pxServer != NULL )
		{
		struct freertos_sockaddr xAddress;
		BaseType_t xNoTimeout = 0;
		BaseType_t xIndex;

			memset( pxServer, '\0', xSize );
			pxServer->xServerCount = xCount;
			pxServer->xSocketSet = xSocketSet;

			for( xIndex = 0; xIndex < xCount; xIndex++ )
			{
			BaseType_t xPortNumber = pxConfigs[ xIndex ].xPortNumber;

				if( xPortNumber > 0 )
				{
				Socket_t xSocket;

					xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
					FreeRTOS_printf( ( "TCP socket on port %d\n", ( int )xPortNumber ) );

					if( xSocket != FREERTOS_INVALID_SOCKET )
					{
						xAddress.sin_addr = FreeRTOS_GetIPAddress(); // Single NIC, currently not used
						xAddress.sin_port = FreeRTOS_htons( xPortNumber );

						FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
						FreeRTOS_listen( xSocket, pxConfigs[ xIndex ].xBackLog );

						FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) );
						FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) );

						#if( ipconfigHTTP_RX_BUFSIZE > 0 )
						{
							if( pxConfigs[ xIndex ].eType == eSERVER_HTTP )
							{
							WinProperties_t xWinProps;

								memset( &xWinProps, '\0', sizeof( xWinProps ) );
								/* The parent socket itself won't get connected.  The properties below
								will be inherited by each new child socket. */
								xWinProps.lTxBufSize = ipconfigHTTP_TX_BUFSIZE;
								xWinProps.lTxWinSize = ipconfigHTTP_TX_WINSIZE;
								xWinProps.lRxBufSize = ipconfigHTTP_RX_BUFSIZE;
								xWinProps.lRxWinSize = ipconfigHTTP_RX_WINSIZE;

								/* Set the window and buffer sizes. */
								FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps,	sizeof( xWinProps ) );
							}
						}
						#endif

						FreeRTOS_FD_SET( xSocket, xSocketSet, eSELECT_READ|eSELECT_EXCEPT );
						pxServer->xServers[ xIndex ].xSocket = xSocket;
						pxServer->xServers[ xIndex ].eType = pxConfigs[ xIndex ].eType;
						pxServer->xServers[ xIndex ].pcRootDir = strnew( pxConfigs[ xIndex ].pcRootDir );
						prvRemoveSlash( ( char * ) pxServer->xServers[ xIndex ].pcRootDir );
					}
				}
			}
		}
		else
		{
			/* Could not allocate the server, delete the socket set */
			FreeRTOS_DeleteSocketSet( xSocketSet );
		}
	}
	else
	{
		/* Could not create a socket set, return NULL */
		pxServer = NULL;
	}

	return pxServer;
}
/*-----------------------------------------------------------*/

static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket )
{
TCPClient_t *pxClient = NULL;
BaseType_t xSize = 0;
FTCPWorkFunction fWorkFunc = NULL;
FTCPDeleteFunction fDeleteFunc = NULL;
const char *pcType = "Unknown";

	/*_RB_ Can the work and delete functions be part of the xSERVER_CONFIG structure
	becomes generic, with no pre-processing required? */
	#if( ipconfigUSE_HTTP != 0 )
	{
		if( pxServer->xServers[ xIndex ].eType == eSERVER_HTTP )
		{
			xSize = sizeof( HTTPClient_t );
			fWorkFunc = xHTTPClientWork;
			fDeleteFunc = vHTTPClientDelete;
			pcType = "HTTP";
		}
	}
	#endif /* ipconfigUSE_HTTP != 0 */

	#if( ipconfigUSE_FTP != 0 )
	{
		if( pxServer->xServers[ xIndex ].eType == eSERVER_FTP )
		{
			xSize = sizeof( FTPClient_t );
			fWorkFunc = xFTPClientWork;
			fDeleteFunc = vFTPClientDelete;
			pcType = "FTP";
		}
	}
	#endif /* ipconfigUSE_FTP != 0 */

	/* Malloc enough space for a new HTTP-client */
	if( xSize )
	{
		pxClient = ( TCPClient_t* ) pvPortMallocLarge( xSize );
	}

	if( pxClient != NULL )
	{
		memset( pxClient, '\0', xSize );

		/* Put the new client in front of the list. */
		pxClient->eType = pxServer->xServers[ xIndex ].eType;
		pxClient->pcRootDir = pxServer->xServers[ xIndex ].pcRootDir;
		pxClient->pxParent = pxServer;
		pxClient->xSocket = xNexSocket;
		pxClient->pxNextClient = pxServer->pxClients;
		pxClient->fWorkFunction = fWorkFunc;
		pxClient->fDeleteFunction = fDeleteFunc;
		pxServer->pxClients = pxClient;

		FreeRTOS_FD_SET( xNexSocket, pxServer->xSocketSet, eSELECT_READ|eSELECT_EXCEPT );
	}
	else
	{
		pcType = "closed";
		FreeRTOS_closesocket( xNexSocket );
	}
	{
	struct freertos_sockaddr xRemoteAddress;
		FreeRTOS_GetRemoteAddress( pxClient->xSocket, &xRemoteAddress );
		FreeRTOS_printf( ( "TPC-server: new %s client %xip\n", pcType, (unsigned)FreeRTOS_ntohl( xRemoteAddress.sin_addr ) ) );
	}

	/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
	( void ) pcType;
}
/*-----------------------------------------------------------*/

void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime )
{
TCPClient_t **ppxClient;
BaseType_t xIndex;
BaseType_t xRc;

	/* Let the server do one working cycle */
	xRc = FreeRTOS_select( pxServer->xSocketSet, xBlockingTime );

	if( xRc != 0 )
	{
		for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
		{
		struct freertos_sockaddr xAddress;
		Socket_t xNexSocket;
		socklen_t xSocketLength;

			if( pxServer->xServers[ xIndex ].xSocket == FREERTOS_NO_SOCKET )
			{
				continue;
			}

			xSocketLength = sizeof( xAddress );
			xNexSocket = FreeRTOS_accept( pxServer->xServers[ xIndex ].xSocket, &xAddress, &xSocketLength);

			if( ( xNexSocket != FREERTOS_NO_SOCKET ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) )
			{
				prvReceiveNewClient( pxServer, xIndex, xNexSocket );
			}
		}
	}

	ppxClient = &pxServer->pxClients;

	while( ( * ppxClient ) != NULL )
	{
	TCPClient_t *pxThis = *ppxClient;

		/* Almost C++ */
		xRc = pxThis->fWorkFunction( pxThis );

		if (xRc < 0 )
		{
			*ppxClient = pxThis->pxNextClient;
			/* Close handles, resources */
			pxThis->fDeleteFunction( pxThis );
			/* Free the space */
			vPortFreeLarge( pxThis );
		}
		else
		{
			ppxClient = &( pxThis->pxNextClient );
		}
	}
}
/*-----------------------------------------------------------*/

static char *strnew( const char *pcString )
{
BaseType_t xLength;
char *pxBuffer;

	xLength = strlen( pcString ) + 1;
	pxBuffer = ( char * ) pvPortMalloc( xLength );
	if( pxBuffer != NULL )
	{
		memcpy( pxBuffer, pcString, xLength );
	}

	return pxBuffer;
}
/*-----------------------------------------------------------*/

static void prvRemoveSlash( char *pcDir )
{
BaseType_t xLength = strlen( pcDir );

	while( ( xLength > 0 ) && ( pcDir[ xLength - 1 ] == '/' ) )
	{
		pcDir[ --xLength ] = '\0';
	}
}
/*-----------------------------------------------------------*/

#if( ipconfigSUPPORT_SIGNALS != 0 )

	/* FreeRTOS_TCPServerWork() calls select().
	The two functions below provide a possibility to interrupt
	the call to select(). After the interruption, resume
	by calling FreeRTOS_TCPServerWork() again. */
	BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer )
	{
	BaseType_t xIndex;
	BaseType_t xResult = pdFALSE;
		for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
		{
			if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET )
			{
				FreeRTOS_SignalSocket( pxServer->xServers[ xIndex ].xSocket );
				xResult = pdTRUE;
				break;
			}
		}

		return xResult;
	}

#endif /* ipconfigSUPPORT_SIGNALS */
/*-----------------------------------------------------------*/

#if( ipconfigSUPPORT_SIGNALS != 0 )

	/* Same as above: this function may be called from an ISR,
	for instance a GPIO interrupt. */
	BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken )
	{
	BaseType_t xIndex;
	BaseType_t xResult = pdFALSE;
		for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
		{
			if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET )
			{
				FreeRTOS_SignalSocketFromISR( pxServer->xServers[ xIndex ].xSocket, pxHigherPriorityTaskWoken );
				xResult = pdTRUE;
				break;
			}
		}

		return xResult;
	}
#endif /* ipconfigSUPPORT_SIGNALS */
/*-----------------------------------------------------------*/

#endif /* ( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) ) */
