/*
 * hdhomerun_sock_windows.c
 *
 * Copyright © 2010 Silicondust USA Inc. <www.silicondust.com>.
 *
 * This library is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * As a special exception to the GNU Lesser General Public License,
 * you may link, statically or dynamically, an application with a
 * publicly distributed version of the Library to produce an
 * executable file containing portions of the Library, and
 * distribute that executable file under terms of your choice,
 * without any of the additional requirements listed in clause 4 of
 * the GNU Lesser General Public License.
 * 
 * By "a publicly distributed version of the Library", we mean
 * either the unmodified Library as distributed by Silicondust, or a
 * modified version of the Library that is distributed under the
 * conditions defined in the GNU Lesser General Public License.
 */

/*
 * Implementation notes:
 *
 * API specifies timeout for each operation (or zero for non-blocking).
 *
 * It is not possible to rely on the OS socket timeout as this will fail to
 * detect the command-response situation where data is sent successfully and
 * the other end chooses not to send a response (other than the TCP ack).
 *
 * Windows supports select() however native WSA events are used to:
 * - avoid problems with socket numbers above 1024.
 * - wait without allowing other events handlers to run (important for use
 *   with win7 WMC).
 */

#include "hdhomerun.h"
#include <windows.h>
#include <iphlpapi.h>

int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count)
{
	PIP_ADAPTER_INFO AdapterInfo;
	ULONG AdapterInfoLength = sizeof(IP_ADAPTER_INFO) * 16;

	while (1) {
		AdapterInfo = (IP_ADAPTER_INFO *)malloc(AdapterInfoLength);
		if (!AdapterInfo) {
			return -1;
		}

		ULONG LengthNeeded = AdapterInfoLength;
		DWORD Ret = GetAdaptersInfo(AdapterInfo, &LengthNeeded);
		if (Ret == NO_ERROR) {
			break;
		}

		free(AdapterInfo);

		if (Ret != ERROR_BUFFER_OVERFLOW) {
			return -1;
		}
		if (AdapterInfoLength >= LengthNeeded) {
			return -1;
		}

		AdapterInfoLength = LengthNeeded;
	}

	int count = 0;
	PIP_ADAPTER_INFO Adapter = AdapterInfo;
	while (Adapter) {
		IP_ADDR_STRING *IPAddr = &Adapter->IpAddressList;
		while (IPAddr) {
			uint32_t ip_addr = ntohl(inet_addr(IPAddr->IpAddress.String));
			uint32_t subnet_mask = ntohl(inet_addr(IPAddr->IpMask.String));

			if (ip_addr == 0) {
				IPAddr = IPAddr->Next;
				continue;
			}

			if (count < max_count) {
				struct hdhomerun_local_ip_info_t *ip_info = &ip_info_list[count];
				ip_info->ip_addr = ip_addr;
				ip_info->subnet_mask = subnet_mask;
			}

			count++;
			IPAddr = IPAddr->Next;
		}

		if (count >= max_count) {
			break;
		}

		Adapter = Adapter->Next;
	}

	free(AdapterInfo);
	return count;
}

hdhomerun_sock_t hdhomerun_sock_create_udp(void)
{
	/* Create socket. */
	hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == -1) {
		return HDHOMERUN_SOCK_INVALID;
	}

	/* Set non-blocking */
	unsigned long mode = 1;
	if (ioctlsocket(sock, FIONBIO, &mode) != 0) {
		closesocket(sock);
		return HDHOMERUN_SOCK_INVALID;
	}

	/* Allow broadcast. */
	int sock_opt = 1;
	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));

	/* Success. */
	return sock;
}

hdhomerun_sock_t hdhomerun_sock_create_tcp(void)
{
	/* Create socket. */
	hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_STREAM, 0);
	if (sock == -1) {
		return HDHOMERUN_SOCK_INVALID;
	}

	/* Set non-blocking */
	unsigned long mode = 1;
	if (ioctlsocket(sock, FIONBIO, &mode) != 0) {
		closesocket(sock);
		return HDHOMERUN_SOCK_INVALID;
	}

	/* Success. */
	return sock;
}

void hdhomerun_sock_destroy(hdhomerun_sock_t sock)
{
	closesocket(sock);
}

int hdhomerun_sock_getlasterror(void)
{
	return WSAGetLastError();
}

uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock)
{
	struct sockaddr_in sock_addr;
	int sockaddr_size = sizeof(sock_addr);

	if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
		return 0;
	}

	return ntohl(sock_addr.sin_addr.s_addr);
}

uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock)
{
	struct sockaddr_in sock_addr;
	int sockaddr_size = sizeof(sock_addr);

	if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
		return 0;
	}

	return ntohs(sock_addr.sin_port);
}

uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock)
{
	struct sockaddr_in sock_addr;
	int sockaddr_size = sizeof(sock_addr);

	if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
		return 0;
	}

	return ntohl(sock_addr.sin_addr.s_addr);
}

uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name)
{
	struct addrinfo hints;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	struct addrinfo *sock_info;
	if (getaddrinfo(name, "", &hints, &sock_info) != 0) {
		return 0;
	}

	struct sockaddr_in *sock_addr = (struct sockaddr_in *)sock_info->ai_addr;
	uint32_t addr = ntohl(sock_addr->sin_addr.s_addr);

	freeaddrinfo(sock_info);
	return addr;
}

bool_t hdhomerun_sock_join_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip)
{
	struct ip_mreq imr;
	memset(&imr, 0, sizeof(imr));
	imr.imr_multiaddr.s_addr  = htonl(multicast_ip);
	imr.imr_interface.s_addr  = htonl(local_ip);

	if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
		return FALSE;
	}

	return TRUE;
}

bool_t hdhomerun_sock_leave_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip)
{
	struct ip_mreq imr;
	memset(&imr, 0, sizeof(imr));
	imr.imr_multiaddr.s_addr  = htonl(multicast_ip);
	imr.imr_interface.s_addr  = htonl(local_ip);

	if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
		return FALSE;
	}

	return TRUE;
}

bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse)
{
	int sock_opt = allow_reuse;
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt));

	struct sockaddr_in sock_addr;
	memset(&sock_addr, 0, sizeof(sock_addr));
	sock_addr.sin_family = AF_INET;
	sock_addr.sin_addr.s_addr = htonl(local_addr);
	sock_addr.sin_port = htons(local_port);

	if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
		return FALSE;
	}

	return TRUE;
}

bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout)
{
	/* Connect (non-blocking). */
	struct sockaddr_in sock_addr;
	memset(&sock_addr, 0, sizeof(sock_addr));
	sock_addr.sin_family = AF_INET;
	sock_addr.sin_addr.s_addr = htonl(remote_addr);
	sock_addr.sin_port = htons(remote_port);

	if (connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
		if (WSAGetLastError() != WSAEWOULDBLOCK) {
			return FALSE;
		}
	}

	/* Wait for connect to complete (both success and failure will signal). */
	WSAEVENT wsa_event = WSACreateEvent();
	if (wsa_event == WSA_INVALID_EVENT) {
		return FALSE;
	}

	if (WSAEventSelect(sock, wsa_event, FD_WRITE | FD_CLOSE) == SOCKET_ERROR) {
		WSACloseEvent(wsa_event);
		return FALSE;
	}

	DWORD ret = WaitForSingleObjectEx(wsa_event, (DWORD)timeout, FALSE);
	WSACloseEvent(wsa_event);
	if (ret != WAIT_OBJECT_0) {
		return FALSE;
	}

	/* Detect success/failure. */
	wsa_event = WSACreateEvent();
	if (wsa_event == WSA_INVALID_EVENT) {
		return FALSE;
	}

	if (WSAEventSelect(sock, wsa_event, FD_CLOSE) == SOCKET_ERROR) {
		WSACloseEvent(wsa_event);
		return FALSE;
	}

	ret = WaitForSingleObjectEx(wsa_event, 0, FALSE);
	WSACloseEvent(wsa_event);
	if (ret == WAIT_OBJECT_0) {
		return FALSE;
	}

	return TRUE;
}

static bool_t hdhomerun_sock_wait_for_event(hdhomerun_sock_t sock, long event_type, uint64_t stop_time)
{
	uint64_t current_time = getcurrenttime();
	if (current_time >= stop_time) {
		return FALSE;
	}

	WSAEVENT wsa_event = WSACreateEvent();
	if (wsa_event == WSA_INVALID_EVENT) {
		return FALSE;
	}

	if (WSAEventSelect(sock, wsa_event, event_type) == SOCKET_ERROR) {
		WSACloseEvent(wsa_event);
		return FALSE;
	}

	DWORD ret = WaitForSingleObjectEx(wsa_event, (DWORD)(stop_time - current_time), FALSE);
	WSACloseEvent(wsa_event);

	if (ret != WAIT_OBJECT_0) {
		return FALSE;
	}

	return TRUE;
}

bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout)
{
	uint64_t stop_time = getcurrenttime() + timeout;
	const uint8_t *ptr = (uint8_t *)data;

	while (1) {
		int ret = send(sock, (char *)ptr, (int)length, 0);
		if (ret <= 0) {
			if (WSAGetLastError() != WSAEWOULDBLOCK) {
				return FALSE;
			}
			if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) {
				return FALSE;
			}
			continue;
		}

		if (ret < (int)length) {
			ptr += ret;
			length -= ret;
			continue;
		}

		return TRUE;
	}
}

bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout)
{
	uint64_t stop_time = getcurrenttime() + timeout;
	const uint8_t *ptr = (uint8_t *)data;

	while (1) {
		struct sockaddr_in sock_addr;
		memset(&sock_addr, 0, sizeof(sock_addr));
		sock_addr.sin_family = AF_INET;
		sock_addr.sin_addr.s_addr = htonl(remote_addr);
		sock_addr.sin_port = htons(remote_port);

		int ret = sendto(sock, (char *)ptr, (int)length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
		if (ret <= 0) {
			if (WSAGetLastError() != WSAEWOULDBLOCK) {
				return FALSE;
			}
			if (!hdhomerun_sock_wait_for_event(sock, FD_WRITE | FD_CLOSE, stop_time)) {
				return FALSE;
			}
			continue;
		}

		if (ret < (int)length) {
			ptr += ret;
			length -= ret;
			continue;
		}

		return TRUE;
	}
}

bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout)
{
	uint64_t stop_time = getcurrenttime() + timeout;

	while (1) {
		int ret = recv(sock, (char *)data, (int)(*length), 0);
		if (ret < 0) {
			if (WSAGetLastError() != WSAEWOULDBLOCK) {
				return FALSE;
			}
			if (!hdhomerun_sock_wait_for_event(sock, FD_READ | FD_CLOSE, stop_time)) {
				return FALSE;
			}
			continue;
		}

		if (ret == 0) {
			return FALSE;
		}

		*length = ret;
		return TRUE;
	}
}

bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout)
{
	uint64_t stop_time = getcurrenttime() + timeout;

	while (1) {
		struct sockaddr_in sock_addr;
		memset(&sock_addr, 0, sizeof(sock_addr));
		int sockaddr_size = sizeof(sock_addr);

		int ret = recvfrom(sock, (char *)data, (int)(*length), 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
		if (ret < 0) {
			if (WSAGetLastError() != WSAEWOULDBLOCK) {
				return FALSE;
			}
			if (!hdhomerun_sock_wait_for_event(sock, FD_READ | FD_CLOSE, stop_time)) {
				return FALSE;
			}
			continue;
		}

		if (ret == 0) {
			return FALSE;
		}

		*remote_addr = ntohl(sock_addr.sin_addr.s_addr);
		*remote_port = ntohs(sock_addr.sin_port);
		*length = ret;
		return TRUE;
	}
}
