/*
 * Copyright (c) 2016 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.
 */

#include "netz.h"

#include <net/net_core.h>
#include <net/net_socket.h>

#include <string.h>
#include <errno.h>

void netz_host(struct netz_ctx_t *ctx, struct net_addr *host)
{
	return netz_host_ipv4(ctx, host->in_addr.in4_u.u4_addr8[0],
				   host->in_addr.in4_u.u4_addr8[1],
				   host->in_addr.in4_u.u4_addr8[2],
				   host->in_addr.in4_u.u4_addr8[3]);
}

void netz_host_ipv4(struct netz_ctx_t *ctx, uint8_t a1, uint8_t a2,
		    uint8_t a3, uint8_t a4)
{
	uip_ipaddr_t host_addr;

	uip_ipaddr(&host_addr, a1, a2, a3, a4);
	uip_sethostaddr(&host_addr);

	ctx->host.in_addr.in4_u.u4_addr8[0] = a1;
	ctx->host.in_addr.in4_u.u4_addr8[1] = a2;
	ctx->host.in_addr.in4_u.u4_addr8[2] = a3;
	ctx->host.in_addr.in4_u.u4_addr8[3] = a4;
	ctx->host.family = AF_INET;
}

void netz_netmask(struct netz_ctx_t *ctx, struct net_addr *netmask)
{
	return netz_netmask_ipv4(ctx, netmask->in_addr.in4_u.u4_addr8[0],
				      netmask->in_addr.in4_u.u4_addr8[1],
				      netmask->in_addr.in4_u.u4_addr8[2],
				      netmask->in_addr.in4_u.u4_addr8[3]);
}

void netz_netmask_ipv4(struct netz_ctx_t *ctx, uint8_t n1, uint8_t n2,
		       uint8_t n3, uint8_t n4)
{
	ARG_UNUSED(ctx);

	uip_ipaddr_t netmask;

	uip_ipaddr(&netmask, n1, n2, n3, n4);
	uip_setnetmask(&netmask);
}

void netz_remote(struct netz_ctx_t *ctx, struct net_addr *remote, int port)
{
	return netz_remote_ipv4(ctx, remote->in_addr.in4_u.u4_addr8[0],
				     remote->in_addr.in4_u.u4_addr8[1],
				     remote->in_addr.in4_u.u4_addr8[2],
				     remote->in_addr.in4_u.u4_addr8[3], port);
}

void netz_remote_ipv4(struct netz_ctx_t *ctx, uint8_t a1, uint8_t a2,
		      uint8_t a3, uint8_t a4, int port)
{
	ctx->remote.in_addr.in4_u.u4_addr8[0] = a1;
	ctx->remote.in_addr.in4_u.u4_addr8[1] = a2;
	ctx->remote.in_addr.in4_u.u4_addr8[2] = a3;
	ctx->remote.in_addr.in4_u.u4_addr8[3] = a4;
	ctx->remote.family = AF_INET;

	ctx->remote_port = port;
}

static int netz_prepare(struct netz_ctx_t *ctx, enum ip_protocol proto)
{
#ifdef CONFIG_NETWORKING_WITH_TCP
	struct app_buf_t buf = APP_BUF_INIT(NULL, 0, 0);
	int rc;
#endif

	ctx->connected = 0;
	ctx->proto = proto;

	ctx->net_ctx = net_context_get(ctx->proto,
				       &ctx->remote, ctx->remote_port,
				       &ctx->host, 0);
	if (ctx->net_ctx == NULL) {
		return -EINVAL;
	}

#ifdef CONFIG_NETWORKING_WITH_TCP
	/* workaround to activate the IP stack */
	rc = netz_tx(ctx, &buf);
	if (rc != 0) {
		return rc;
	}
#endif
	ctx->connected = 1;
	return 0;
}

int netz_tcp(struct netz_ctx_t *ctx)
{
	return netz_prepare(ctx, IPPROTO_TCP);
}

int netz_udp(struct netz_ctx_t *ctx)
{
	return netz_prepare(ctx, IPPROTO_UDP);
}

static void netz_sleep(int sleep_ticks)
{
	struct nano_timer timer;

	nano_timer_init(&timer, NULL);
	nano_fiber_timer_start(&timer, sleep_ticks);
	nano_fiber_timer_test(&timer, TICKS_UNLIMITED);
}

static int tcp_tx(struct net_context *ctx, uint8_t *buf, size_t size,
		  int tx_retry_timeout)
{
	struct net_buf *nbuf;
	uint8_t *ptr;
	int rc;

	nbuf = ip_buf_get_tx(ctx);
	if (nbuf == NULL) {
		return -EINVAL;
	}

	ptr = net_buf_add(nbuf, size);
	memcpy(ptr, buf, size);
	ip_buf_appdatalen(nbuf) = size;

	do {
		rc = net_send(nbuf);

		if (rc >= 0) {
			ip_buf_unref(nbuf);
			return 0;
		}
		switch (rc) {
		case -EINPROGRESS:
			netz_sleep(tx_retry_timeout);
			break;
		case -EAGAIN:
		case -ECONNRESET:
			netz_sleep(tx_retry_timeout);
			break;
		default:
			ip_buf_unref(nbuf);
			return -EIO;
		}
	} while (1);

	return 0;
}

static int tcp_rx(struct net_context *ctx, uint8_t *buf, size_t *read_bytes,
		  size_t size, int rx_timeout)
{
	struct net_buf *nbuf;
	int rc;

	nbuf = net_receive(ctx, rx_timeout);
	if (nbuf == NULL) {
		return -EIO;
	}

	*read_bytes = ip_buf_appdatalen(nbuf);
	if (*read_bytes > size) {
		*read_bytes = size;
		rc = -ENOMEM;
	} else {
		rc = 0;
	}

	memcpy(buf, ip_buf_appdata(nbuf), *read_bytes);
	ip_buf_unref(nbuf);

	return rc;
}

int netz_tx(struct netz_ctx_t *ctx, struct app_buf_t *buf)
{
	int rc;

	/* We don't evaluate if we are connected. */

	rc = tcp_tx(ctx->net_ctx, buf->buf, buf->length,
		    ctx->tx_retry_timeout);

	return rc;
}

int netz_rx(struct netz_ctx_t *ctx, struct app_buf_t *buf)
{
	int rc;

	if (ctx->connected != 1) {
		return -ENOTCONN;
	}

	rc = tcp_rx(ctx->net_ctx, buf->buf, &buf->length, buf->size,
		    ctx->rx_timeout);

	return rc;
}
