/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "settings_test.h"
#include "settings_priv.h"

static char enc_buf[128];
static int enc_buf_cnt;
static u8_t test_rwbs = 1U;
#define ENC_CTX_VAL 0x2018

static int write_handler(void *ctx, off_t off, char const *buf, size_t len)
{
	zassert_equal(ctx, (void *)ENC_CTX_VAL, "bad write calback context\n");

	if (off % test_rwbs || len % test_rwbs) {
		return -EIO;
	}

	memcpy(&enc_buf[off], buf, len);
	enc_buf_cnt += len;
	return 0;
}

static void test_encoding_iteration(char const *name, char const *value,
				    char const *pattern, int exp_len, u8_t wbs)
{
	int rc;

	test_rwbs = wbs;

	settings_line_io_init(NULL, write_handler, NULL, wbs);

	enc_buf_cnt = 0;

	rc = settings_line_write(name, value, strlen(value), 0,
				 (void *)ENC_CTX_VAL);

	zassert_equal(rc, 0, "Can't encode the line %d.\n", rc);

	zassert_equal(enc_buf_cnt, exp_len, "Wrote more than expected\n");

	zassert_true(memcmp(pattern, enc_buf, exp_len) == 0,
		     "encoding defect, was     : %s\nexpected: %s\n", enc_buf,
		     pattern);
}

void test_settings_encode(void)
{
	char const name[] = "nordic";
	char const value[] = "Doubt. Only an evil man, master Geralt,"
			     " is without it. And no one escapes his destiny";
	char const pattern[] = "nordic=RG91YnQuIE9ubHkgYW4gZXZpbCBtYW4sIG1hc3Rl"
			       "ciBHZXJhbHQsIGlzIHdpdGhvdXQgaXQuIEFuZCBubyBvbmU"
			       "gZXNjYXBlcyBoaXMgZGVzdGlueQ==\0";
	char const pattern2[] = "nordic=RG91YnQuIE9ubHkgYW4gZXZpbCBtYW4sIG1hc3R"
				"lciBHZXJhbHQsIGlzIHdpdGhvdXQgaXQuIEFuZCBubyBvb"
				"mUgZXNjYXBlcyBoaXMgZGVzdGlueQ==\0\0\0\0\0";
	char const name2[] = "nord";
	char const value2[] = "123";
	char const pattern3[] = "nord=MTIz\0\0\0";

	test_encoding_iteration(name, value, pattern, 124, 4);
	test_encoding_iteration(name, value, pattern, 123, 1);
	test_encoding_iteration(name, value, pattern2, 128, 8);
	test_encoding_iteration(name2, value2, pattern3, 12, 4);
	test_encoding_iteration(name2, value2, pattern3, 9, 1);
}

static int read_handle(void *ctx, off_t off, char *buf, size_t *len)
{
	int r_len;

	zassert_equal(ctx, (void *)ENC_CTX_VAL, "bad write calback context\n");

	if (off % test_rwbs || *len % test_rwbs) {
		return -EIO;
	}

	r_len = MIN(sizeof(enc_buf) - off, *len);
	if (r_len <= 0) {
		*len = 0;
		return 0;
	}

	memcpy(buf, &enc_buf[off], r_len);
	*len = r_len;
	return 0;
}

char read_buf[128+10];

void test_raw_read_iteration(u8_t rbs, size_t off, size_t len)
{
	test_rwbs = rbs;
	size_t len_read;
	int rc;
	size_t expected;

	memset(read_buf, 0x00, sizeof(read_buf));

	settings_line_io_init(read_handle, write_handler, NULL, rbs);

	rc = settings_line_raw_read(off, &read_buf[4], len, &len_read,
				    (void *)ENC_CTX_VAL);

	zassert_equal(rc, 0, "Can't read the line %d.\n", rc);

	expected = MIN((sizeof(enc_buf) - off), len);
	zassert_equal(expected, len_read, "Unexpected read size\n");

	zassert_true(memcmp(&enc_buf[off], &read_buf[4], len_read) == 0,
			    "read defect\n");

	for (rc = 0; rc < 4; rc++) {
		zassert_equal(read_buf[rc], 0, "buffer lickage\n");
	}

	for (rc = len_read + 4; rc < sizeof(read_buf); rc++) {
		zassert_equal(read_buf[rc], 0, "buffer lickage\n");
	}
}

void test_setting_raw_read(void)
{
	int i;

	for (i = 0; i < sizeof(enc_buf); i++) {
		enc_buf[i] = i + 1;
	}

	test_raw_read_iteration(1, 0, 56);
	test_raw_read_iteration(1, 5, 128);
	test_raw_read_iteration(4, 1, 56);
	test_raw_read_iteration(4, 0, 128);
	test_raw_read_iteration(4, 3, 128);
	test_raw_read_iteration(8, 3, 128);
	test_raw_read_iteration(8, 0, 128);
	test_raw_read_iteration(8, 77, 3);
}




void test_val_read_iteration(char const *src, size_t src_len,
			     char const *pattern, size_t pattern_len,
			     size_t len, u8_t rbs, size_t off, size_t val_off)
{
	size_t len_read;
	int rc;

	memcpy(enc_buf, src, src_len);

	test_rwbs = rbs;

	settings_line_io_init(read_handle, write_handler, NULL, rbs);

	rc =  settings_line_val_read(val_off, off, read_buf, len, &len_read,
				     (void *)ENC_CTX_VAL);

	zassert_equal(rc, 0, "Can't read the value.\n");

	zassert_equal(len_read, pattern_len, "Bad length (was %d).\n",
		      len_read);
	read_buf[len_read] = 0;
	zassert_true(memcmp(pattern, read_buf, pattern_len) == 0,
		     "encoding defect, was :\n%s\nexpected :\n%s\n", read_buf,
		     pattern);
}

void test_setting_val_read(void)
{
	char const val_src[] = "V2FzIHdyaXR0ZW4gaW4gS3Jha293AA==";
	char const val_src2[] = "jozef/pilsodski="
				"V2FzIHdyaXR0ZW4gaW4gS3Jha293AA==";
	char const val_pattern[] = "Was written in Krakow";

	test_val_read_iteration(val_src, sizeof(val_src), val_pattern,
				sizeof(val_pattern), 128, 1, 0, 0);
	test_val_read_iteration(val_src, sizeof(val_src), &val_pattern[1],
				sizeof(val_pattern) - 1, 128, 1, 1, 0);
	test_val_read_iteration(val_src, sizeof(val_src), val_pattern,
				sizeof(val_pattern), sizeof(val_pattern), 1, 0,
				0);

	for (int j = 1; j < sizeof(val_pattern); j++) {
		for (int i = 0; i < sizeof(val_pattern) - j; i++) {
			test_val_read_iteration(val_src, sizeof(val_src),
						&val_pattern[i], j, j, 1, i, 0);
		}
	}

	for (int j = 1; j < sizeof(val_pattern); j++) {
		for (int i = 0; i < sizeof(val_pattern) - j; i++) {
			test_val_read_iteration(val_src2, sizeof(val_src2),
						&val_pattern[i], j, j, 1, i,
						16);
		}
	}

	test_val_read_iteration(val_src, sizeof(val_src), val_pattern,
				sizeof(val_pattern), 128, 4, 0, 0);
	test_val_read_iteration(val_src, sizeof(val_src), &val_pattern[1],
				sizeof(val_pattern) - 1, 128, 4, 1, 0);
	test_val_read_iteration(val_src, sizeof(val_src), val_pattern,
				sizeof(val_pattern), sizeof(val_pattern), 4, 0,
				0);

	for (int j = 1; j < sizeof(val_pattern); j++) {
		for (int i = 0; i < sizeof(val_pattern) - j; i++) {
			test_val_read_iteration(val_src, sizeof(val_src),
						&val_pattern[i], j, j, 4, i, 0);
		}
	}

	test_val_read_iteration(val_src, sizeof(val_src), val_pattern,
				sizeof(val_pattern), 128, 8, 0, 0);
	test_val_read_iteration(val_src, sizeof(val_src), &val_pattern[1],
				sizeof(val_pattern) - 1, 128, 8, 1, 0);
	test_val_read_iteration(val_src, sizeof(val_src), val_pattern,
				sizeof(val_pattern), sizeof(val_pattern), 8, 0,
				0);

	for (int j = 1; j < sizeof(val_pattern); j++) {
		for (int i = 0; i < sizeof(val_pattern) - j; i++) {
			test_val_read_iteration(val_src, sizeof(val_src),
						&val_pattern[i], j, j, 8, i, 0);
		}
	}


}
