// socket for winsock2		(C) H.Niwa 1993-2012

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */


#include "config.h"

#include <stdio.h>
#include <string>

#ifdef __MINGW32__
#include <windows.h>
#include <winsock2.h>

#include "winsock2util.h"

#define BUFFER_SIZE 256

void RetrySleep(int t)
{
	Sleep(1000*t);
}

void winsock2init()
{
	WSADATA wsaData;
	int err = WSAStartup(MAKEWORD(2,0), &wsaData);
	if (err != 0) {
		fprintf(stderr, "winsock2 error : %d\n", err);
		exit(-1);
	}
}

void winsock2end()
{
	WSACleanup();
}


void tcppr(SOCKET sock, const char* sendtext)
{
	int i;
	int sendtextlen = strlen(sendtext);

	for (i = 0; i < sendtextlen; ) {
		int plen = strlen(&sendtext[i]);
		if (plen >= BUFFER_SIZE) {
			send(sock, &sendtext[i], BUFFER_SIZE, 0);
			i += BUFFER_SIZE;
		} else {
			send(sock, &sendtext[i], strlen(&sendtext[i]), 0);
			i += strlen(&sendtext[i]);
			break;
		}
	}
}

SOCKET tcpopen(const char* hostname, const char* path, const char* port)
{
	SOCKET sock;
	unsigned int **res;
	struct sockaddr_in dstAddr;

	int portno = strtol(port, NULL, 10);
	if (portno <= 0) {
		portno = 80;
	}

	sock = socket(AF_INET, SOCK_STREAM, 0);

	dstAddr.sin_family = AF_INET;
	dstAddr.sin_port = htons(portno);

	dstAddr.sin_addr.S_un.S_addr = inet_addr(hostname);
	if (dstAddr.sin_addr.S_un.S_addr == 0xffffffff) {
		struct hostent *host;

		host = gethostbyname(hostname);
		if (host == NULL) {
			fprintf(stderr, "can't find %s:%s\n", hostname, port);
			return -1;
		}

		

		for (res = (unsigned int **)host->h_addr_list;
				*res != NULL; res++) {
			dstAddr.sin_addr.S_un.S_addr = *(*res);

			if (connect(sock, (struct sockaddr *)&dstAddr,
						sizeof(dstAddr)) == 0) {
				break;
			}
	 	}
	 	if (*res == NULL) {
			fprintf(stderr, "can't find %s:%s\n", hostname, port);
			return -1;
		}	 		
 	} else {
		if (connect(sock, (struct sockaddr *)&dstAddr, sizeof(dstAddr)) != 0) {
			fprintf(stderr, "can't find %s:%s\n", hostname, port);
			return -1;
		}
	}


	return sock;
}

void tcprecv(std::string &recvtextbody, SOCKET sock)
{
	char buffer[BUFFER_SIZE+1];

	for (;;) {
		int recvlength = recv(sock, buffer, BUFFER_SIZE, 0);
		if (recvlength == 0) {
			break;
		}
		buffer[recvlength] = 0;
		recvtextbody += buffer;
	}		
}

void tcpclose(SOCKET sock)
{
	closesocket(sock);
}


#endif /* __MINGW32__ */

