/*   
Copyright 2006 - 2011 Intel Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#if defined(WIN32)
	#ifndef MICROSTACK_NO_STDAFX
		#include "stdafx.h"
	#endif
	#define _CRTDBG_MAP_ALLOC
	#include <TCHAR.h>
#endif

#if defined(WINSOCK2)
	#include <winsock2.h>
	#include <ws2tcpip.h>
#elif defined(WINSOCK1)
	#include <winsock.h>
	#include <wininet.h>
#endif
#include "ILibParsers.h"
#include "ILibWebServer.h"
#include "ILibAsyncSocket.h"

#if defined(WIN32)
	#include <crtdbg.h>
#endif

#include "{{{INCLUDEHFILE}}}"

void *MicroStackChain;
ILibWebServer_ServerToken WebServerObject;

#if !defined(WIN32)
int WaitForExit = 0;
void* ILib_Monitor;
void ILib_LinuxQuit(void *data)
{
	UNREFERENCED_PARAMETER( data );

	if(MicroStackChain != NULL)
	{
		ILibStopChain(MicroStackChain);
		MicroStackChain = NULL;
	}
}
void BreakSink(int s)
{
	if(WaitForExit == 0)
	{
		ILibLifeTime_Add(ILib_Monitor, NULL, 0, (void*)&ILib_LinuxQuit, NULL);
		WaitForExit = 1;
	}
}
#else
DWORD WINAPI Run(LPVOID args)
{
	UNREFERENCED_PARAMETER( args );
	
	getchar();


	ILibStopChain(MicroStackChain);
	return 0;
}
#endif


void OnReceive(struct ILibWebServer_Session *sender, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, int done)
{
	struct packetheader *response;

	if(done!=0)
	{
		if(header->DirectiveLength==3 && strncasecmp(header->Directive, "GET",3)==0)
		{
			response = ILibCreateEmptyPacket();
			response->UserAllocStrings = 0;

			response->StatusCode = 200;
			response->StatusData = "OK";
			response->StatusDataLength = 2;
			ILibAddHeaderLine(response, "Content-Encoding", 16, "gzip", 4);
			
			response->Body = (char*){{{VARIABLE}}};
			response->BodyLength = {{{VARIABLELEN}}};
			

			ILibWebServer_Send(sender, response);
			*beginPointer = endPointer;
		}
	}
}

void OnSession(struct ILibWebServer_Session *SessionToken, void *User)
{
	SessionToken->OnReceive = &OnReceive;
}

//void OnVirtualDirectory(struct ILibWebServer_Session *session, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, int done, void *user)
//{
//}

#if defined(WIN32)
int _tmain(int argc, _TCHAR* argv[]) 
#else
int main(void)
#endif
{
#if defined(WIN32)
	DWORD ptid = 0;
	DWORD ptid2 = 0;
#else
	struct sigaction setup_action;
    sigset_t block_mask;
#endif

	UNREFERENCED_PARAMETER( argc );
	UNREFERENCED_PARAMETER( argv );

#if defined(WIN32)
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif

	MicroStackChain = ILibCreateChain();
	WebServerObject = ILibWebServer_Create(MicroStackChain, 5, 8080, &OnSession, NULL);
	//ILibWebServer_RegisterVirtualDirectory(WebServerObject, "Test", 4, &OnVirtualDirectory, NULL);

	printf("MicroStack 1.0 - Embedded Web Server \r\n\r\n");

#if defined(WIN32)
	printf("   Press Enter to stop server");
	CreateThread(NULL, 0, &Run, NULL, 0, &ptid);
#else
	ILib_Monitor = ILibCreateLifeTime(MicroStackChain);

	printf("   Press ^C to stop the server\r\n");
	sigemptyset(&block_mask);
	// Block other terminal-generated signals while handler runs.
    sigaddset(&block_mask, SIGINT);
    sigaddset(&block_mask, SIGQUIT);
    setup_action.sa_handler = BreakSink;
    setup_action.sa_mask = block_mask;
    setup_action.sa_flags = 0;
    sigaction(SIGINT, &setup_action, NULL);
	WaitForExit = 0;
#endif

	ILibStartChain(MicroStackChain);
	return 0;
}

