/*
 * Copyright (c) 2019 Linaro Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/device.h>

#include <zephyr/net/socket.h>

#include <zephyr/drivers/video.h>

#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main);

#define MY_PORT 5000
#define MAX_CLIENT_QUEUE 1

static ssize_t sendall(int sock, const void *buf, size_t len)
{
	while (len) {
		ssize_t out_len = send(sock, buf, len, 0);

		if (out_len < 0) {
			return out_len;
		}
		buf = (const char *)buf + out_len;
		len -= out_len;
	}

	return 0;
}

void main(void)
{
	struct sockaddr_in addr, client_addr;
	socklen_t client_addr_len = sizeof(client_addr);
	struct video_buffer *buffers[2], *vbuf;
	int i, ret, sock, client;
	struct video_format fmt;
	const struct device *const video = DEVICE_DT_GET_ONE(nxp_imx_csi);

	/* Prepare Network */
	(void)memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(MY_PORT);

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock < 0) {
		LOG_ERR("Failed to create TCP socket: %d", errno);
		return;
	}

	ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
	if (ret < 0) {
		LOG_ERR("Failed to bind TCP socket: %d", errno);
		close(sock);
		return;
	}

	ret = listen(sock, MAX_CLIENT_QUEUE);
	if (ret < 0) {
		LOG_ERR("Failed to listen on TCP socket: %d", errno);
		close(sock);
		return;
	}

	if (!device_is_ready(video)) {
		LOG_ERR("%s: device not ready.\n", video->name);
		return;
	}

	/* Get default/native format */
	if (video_get_format(video, VIDEO_EP_OUT, &fmt)) {
		LOG_ERR("Unable to retrieve video format");
		return;
	}

	printk("Video device detected, format: %c%c%c%c %ux%u\n",
	       (char)fmt.pixelformat, (char)(fmt.pixelformat >> 8),
	       (char)(fmt.pixelformat >> 16), (char)(fmt.pixelformat >> 24),
	       fmt.width, fmt.height);

	/* Alloc Buffers */
	for (i = 0; i < ARRAY_SIZE(buffers); i++) {
		buffers[i] = video_buffer_alloc(fmt.pitch * fmt.height);
		if (buffers[i] == NULL) {
			LOG_ERR("Unable to alloc video buffer");
			return;
		}
	}

	/* Connection loop */
	do {
		printk("TCP: Waiting for client...\n");

		client = accept(sock, (struct sockaddr *)&client_addr,
				&client_addr_len);
		if (client < 0) {
			printk("Failed to accept: %d\n", errno);
			return;
		}

		printk("TCP: Accepted connection\n");

		/* Enqueue Buffers */
		for (i = 0; i < ARRAY_SIZE(buffers); i++) {
			video_enqueue(video, VIDEO_EP_OUT, buffers[i]);
		}

		/* Start video capture */
		if (video_stream_start(video)) {
			LOG_ERR("Unable to start video");
			return;
		}

		printk("Stream started\n");

		/* Capture loop */
		i = 0;
		do {
			ret = video_dequeue(video, VIDEO_EP_OUT, &vbuf,
					    K_FOREVER);
			if (ret) {
				LOG_ERR("Unable to dequeue video buf");
				return;
			}

			printk("\rSending frame %d", i++);

			/* Send video buffer to TCP client */
			ret = sendall(client, vbuf->buffer, vbuf->bytesused);
			if (ret && ret != -EAGAIN) {
				/* client disconnected */
				printk("\nTCP: Client disconnected %d\n", ret);
				close(client);
			}

			(void)video_enqueue(video, VIDEO_EP_OUT, vbuf);
		} while (!ret);

		/* stop capture */
		if (video_stream_stop(video)) {
			LOG_ERR("Unable to stop video");
			return;
		}

		/* Flush remaining buffers */
		do {
			ret = video_dequeue(video, VIDEO_EP_OUT,
					    &vbuf, K_NO_WAIT);
		} while (!ret);

	} while (1);
}
