/**
 * Copyright © 2019 IBM 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 <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>

#include "util.h"

static ssize_t __read(int fd, void *buf, size_t len);
#define read __read
#include "config.c"
#include "console-socket.c"
#define main __main
#include "console-client.c"
#undef read
#undef main

struct test {
	enum esc_type esc_type;
	union {
		struct ssh_esc_state ssh;
		struct str_esc_state str;
	} esc_state;
	const char *in[4];
	size_t n_in;
	const char *exp_out;
	int exp_rc;
};

struct test_ctx {
	struct console_client client;
	struct test *test;
	uint8_t out[4096];
	size_t cur_in;
	size_t cur_out;
};

struct test tests[] = {
	{
		/* no escape code */
		.esc_type = ESC_TYPE_SSH,
		.in = { "a" },
		.n_in = 1,
		.exp_out = "a",
		.exp_rc = PROCESS_EXIT,
	},
	{
		/* no escape code, multiple reads */
		.esc_type = ESC_TYPE_SSH,
		.in = { "a", "b" },
		.n_in = 2,
		.exp_out = "ab",
		.exp_rc = PROCESS_EXIT,
	},
	{
		/* ssh escape in one read */
		.esc_type = ESC_TYPE_SSH,
		.in = { "a\r~." },
		.n_in = 1,
		.exp_out = "a\r",
		.exp_rc = PROCESS_ESC,
	},
	{
		/* ssh escape, partial ~ is not output. */
		.esc_type = ESC_TYPE_SSH,
		.in = { "a\r~" },
		.n_in = 1,
		.exp_out = "a\r",
		.exp_rc = PROCESS_EXIT,
	},
	{
		/* ssh escape split into individual reads */
		.esc_type = ESC_TYPE_SSH,
		.in = { "a", "\r", "~", "." },
		.n_in = 4,
		.exp_out = "a\r",
		.exp_rc = PROCESS_ESC,
	},
	{
		/* ssh escape, escaped. */
		.esc_type = ESC_TYPE_SSH,
		.in = { "a\r~~." },
		.n_in = 1,
		.exp_out = "a\r~.",
		.exp_rc = PROCESS_EXIT,
	},
	{
		/* ssh escape, escaped ~, and not completed. */
		.esc_type = ESC_TYPE_SSH,
		.in = { "a\r~~" },
		.n_in = 1,
		.exp_out = "a\r~",
		.exp_rc = PROCESS_EXIT,
	},
	{
		/* str escape, no match */
		.esc_type = ESC_TYPE_STR,
		.esc_state = { .str = { .str = (const uint8_t *)"c" } },
		.in = { "ab" },
		.n_in = 1,
		.exp_out = "ab",
		.exp_rc = PROCESS_EXIT,
	},
	{
		/* str escape, one byte, as one read */
		.esc_type = ESC_TYPE_STR,
		.esc_state = { .str = { .str = (const uint8_t *)"b" } },
		.in = { "abc" },
		.n_in = 1,
		.exp_out = "ab",
		.exp_rc = PROCESS_ESC,
	},
	{
		/* str escape, multiple bytes, as one read */
		.esc_type = ESC_TYPE_STR,
		.esc_state = { .str = { .str = (const uint8_t *)"bc" } },
		.in = { "abcd" },
		.n_in = 1,
		.exp_out = "abc",
		.exp_rc = PROCESS_ESC,
	},
	{
		/* str escape, multiple bytes, split over reads */
		.esc_type = ESC_TYPE_STR,
		.esc_state = { .str = { .str = (const uint8_t *)"bc" } },
		.in = { "ab", "cd" },
		.n_in = 2,
		.exp_out = "abc",
		.exp_rc = PROCESS_ESC,
	},
	{
		/* str escape, not matched due to intermediate data */
		.esc_type = ESC_TYPE_STR,
		.esc_state = { .str = { .str = (const uint8_t *)"ab" } },
		.in = { "acb" },
		.n_in = 1,
		.exp_out = "acb",
		.exp_rc = PROCESS_EXIT,
	},
};

struct test_ctx ctxs[ARRAY_SIZE(tests)];

int write_buf_to_fd(int fd, const uint8_t *buf, size_t len)
{
	struct test_ctx *ctx = &ctxs[fd];

	assert(ctx->cur_out + len <= sizeof(ctx->out));
	memcpy(ctx->out + ctx->cur_out, buf, len);
	ctx->cur_out += len;

	return 0;
}

static ssize_t __read(int fd, void *buf, size_t len)
{
	struct test_ctx *ctx = &ctxs[fd];
	const char *inbuf;
	size_t inlen;

	if (len > SSIZE_MAX) {
		errno = EINVAL;
		return -1;
	}

	if (ctx->cur_in >= ctx->test->n_in) {
		return 0;
	}

	inbuf = ctx->test->in[ctx->cur_in];
	inlen = strlen(inbuf);
	assert(inlen <= len);
	memcpy(buf, inbuf, inlen);
	ctx->cur_in++;
	return (ssize_t)inlen;
}

void run_one_test(size_t idx, struct test *test, struct test_ctx *ctx)
{
	size_t exp_out_len;
	int rc;

	/* we store the index into the context array as a FD, so we
	 * can refer to it through the read & write callbacks.
	 */
	assert(idx < INT_MAX);
	ctx->client.console_sd = (int)idx;
	ctx->client.fd_in = (int)idx;
	ctx->client.esc_type = test->esc_type;
	memcpy(&ctx->client.esc_state, &test->esc_state,
	       sizeof(test->esc_state));
	ctx->test = test;

	for (;;) {
		rc = process_tty(&ctx->client);
		if (rc != PROCESS_OK) {
			break;
		}
	}

	exp_out_len = strlen(test->exp_out);

#ifdef DEBUG
	printf("got: rc %d %s(%d), exp: rc %d %s(%ld)\n", rc, ctx->out,
	       ctx->cur_out, test->exp_rc, test->exp_out, exp_out_len);
	fflush(stdout);
#endif
	assert(rc == test->exp_rc);
	assert(exp_out_len == ctx->cur_out);
	assert(!memcmp(ctx->out, test->exp_out, exp_out_len));
}

int main(void)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(tests); i++) {
		run_one_test(i, &tests[i], &ctxs[i]);
	}

	return EXIT_SUCCESS;
}
