use bufio;
use io;
use encoding::utf8;
use strings;
use memio;
use fmt;

// Reads records from an io::handle and returns them. The result must be freed
// using [[freerecords]].
export fn readrecords(r: io::handle) ([][]str | io::error | utf8::invalid) = {
	const sc = bufio::newscanner(r);
	defer bufio::finish(&sc);

	let records: [][]str = [];
	for (const line: str => bufio::scan_line(&sc)?) {
		append(records, strings::dupall(strings::split(line, "\t")))!;
	};
	return records;
};

// Frees all the records.
export fn freerecords(records: [][]str) void = {
	for (const record .. records) {
		strings::freeall(record);
	};
	free(records);
};

@test fn readnormal() void = {
	const b = strings::toutf8("col1\tcol2\tcol3
1\t2\t3
4\t5\t6\n"
);
	const st = memio::fixed(b);

	const expected = [
		["col1", "col2", "col3"],
		["1", "2", "3"],
		["4", "5", "6"],
	];

	const actual = readrecords(&st)!;
	defer freerecords(actual);
	for (let i = 0z; i < len(expected); i += 1) {
		for (let j = 0z; j < len(actual); j += 1) {
			const exp = expected[i][j];
			const act = actual[i][j];
			fmt::errorfln("exp: {}", exp)!;
			fmt::errorfln("act: {}", act)!;
			assert(exp == act);
		};
	};
};
