/*
 * Copyright (c) 2010-2011 Apple Inc. All rights reserved.
 *
 * @APPLE_APACHE_LICENSE_HEADER_START@
 *
 * 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.
 *
 * @APPLE_APACHE_LICENSE_HEADER_END@
 */

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#endif
#include <errno.h>
#include <fts.h>
#ifdef __APPLE__
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <libkern/OSAtomic.h>
#include <TargetConditionals.h>
#endif
#include <Block.h>

#include <dispatch/dispatch.h>

#include <bsdtests.h>
#include "dispatch_test.h"

#ifndef DISPATCHTEST_IO
#if DISPATCH_API_VERSION >= 20100226 && DISPATCH_API_VERSION != 20101110
#define DISPATCHTEST_IO 1
#endif
#endif

static void
test_fin(void *cxt)
{
	test_ptr("test_fin run", cxt, cxt);
	test_stop();
}

#if DISPATCHTEST_IO

/*
 Basic way of implementing dispatch_io's dispatch_read without
 using dispatch channel api's
 */
static void
dispatch_read2(dispatch_fd_t fd,
			  size_t length,
			  dispatch_queue_t queue,
			  void (^handler)(dispatch_data_t d, int error))
{
	if (fcntl(fd, F_SETFL, O_NONBLOCK) != 0) {
		test_errno("fcntl O_NONBLOCK", errno, 0);
		test_stop();
	}
	dispatch_source_t reader = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ,
			(uintptr_t)fd, 0, queue);
	test_ptr_notnull("reader", reader);

	__block size_t bytes_read = 0;
	__block dispatch_data_t data = dispatch_data_empty;
	__block int err = 0;
	dispatch_source_set_event_handler(reader, ^{
		const ssize_t bufsiz = 1024*512; // 512KB buffer
		char *buffer = valloc(bufsiz);
		ssize_t actual = read(fd, buffer, bufsiz);
		if (actual == -1) {
			err = errno;
		}
		if (actual > 0) {
			bytes_read += (size_t)actual;
			dispatch_data_t tmp_data = dispatch_data_create(buffer, (size_t)actual,
					NULL, DISPATCH_DATA_DESTRUCTOR_FREE);
			dispatch_data_t concat = dispatch_data_create_concat(data,tmp_data);
			dispatch_release(tmp_data);
			dispatch_release(data);
			data = concat;
		}
		// If we reached EOF or we read as much we were asked to.
		if (actual < bufsiz || bytes_read >= length) {
			char foo[2];
			actual = read(fd, foo, 2);
			bytes_read += (size_t)actual;
			// confirm EOF condition
			test_long("EOF", actual, 0);
			dispatch_source_cancel(reader);
		}
	});

	dispatch_source_set_cancel_handler(reader, ^{
		dispatch_data_t d = dispatch_data_create_subrange(data, 0, length);
		dispatch_release(data);
		handler(d, err);
		dispatch_release(d);
		dispatch_release(reader);
	});

	dispatch_resume(reader);
}

static void
test_read(void)
{
	const char *path = "/usr/bin/vi";
	int fd = open(path, O_RDONLY);
	if (fd == -1) {
		test_errno("open", errno, 0);
		test_stop();
	}
#ifdef F_NOCACHE
	if (fcntl(fd, F_NOCACHE, 1)) {
		test_errno("fcntl F_NOCACHE", errno, 0);
		test_stop();
	}
#else
	// investigate what the impact of lack of file cache disabling has 
	// for this test
#endif
	struct stat sb;
	if (fstat(fd, &sb)) {
		test_errno("fstat", errno, 0);
		test_stop();
	}
	size_t size = (size_t)sb.st_size;
	dispatch_group_t g = dispatch_group_create();
	void (^b)(dispatch_data_t, int) = ^(dispatch_data_t d, int error) {
		test_errno("read error", error, 0);
		test_sizet("dispatch data size", d ? dispatch_data_get_size(d) : 0, size);
		if (d) {
			const void *contig_buf;
			size_t contig_size;
			dispatch_data_t tmp = dispatch_data_create_map(d, &contig_buf,
					&contig_size);
			test_sizet("dispatch data contig size", contig_size, size);
			if (contig_size) {
				// Validate the copied buffer is similar to what we expect
				char *buf = (char*)malloc(size);
				pread(fd, buf, size, 0);
				test_long("dispatch data contents", memcmp(buf, contig_buf,
						size), 0);
				free(buf);
			}
			dispatch_release(tmp);
		}
		dispatch_group_leave(g);
	};
	dispatch_group_enter(g);
	dispatch_read(fd, SIZE_MAX, dispatch_get_global_queue(0, 0), b); // rdar://problem/7795794
	test_group_wait(g);
	lseek(fd, 0, SEEK_SET);
	if (dispatch_test_check_evfilt_read_for_fd(fd)) {
		dispatch_group_enter(g);
		dispatch_read2(fd, size, dispatch_get_global_queue(0,0), b);
		test_group_wait(g);
	} else {
		test_skip("EVFILT_READ kevent not firing for test file");
	}
	dispatch_release(g);
	close(fd);
}

static void
test_read_write(void)
{
	const char *path_in = "/dev/urandom";
	char path_out[] = "/tmp/dispatchtest_io.XXXXXX";
	const size_t siz_in = 10240;

	int in = open(path_in, O_RDONLY);
	if (in == -1) {
		test_errno("open", errno, 0);
		test_stop();
	}
	int out = mkstemp(path_out);
	if (out == -1) {
		test_errno("mkstemp", errno, 0);
		test_stop();
	}
	if (unlink(path_out) == -1) {
		test_errno("unlink", errno, 0);
		test_stop();
	}
	dispatch_queue_t q = dispatch_get_global_queue(0,0);
	dispatch_group_t g = dispatch_group_create();
	dispatch_group_enter(g);
	__block dispatch_data_t data;
	dispatch_read(in, siz_in, q, ^(dispatch_data_t data_in, int err_in) {
		if (err_in) {
			test_errno("dispatch_read", err_in, 0);
			test_stop();
		}
		close(in);
		size_t siz_out = dispatch_data_get_size(data_in);
		test_sizet("read size", siz_out, siz_in);
		dispatch_retain(data_in);
		data = data_in;
		dispatch_write(out, data, q, ^(dispatch_data_t data_out, int err_out) {
			if (err_out || data_out) {
				test_errno("dispatch_write", err_out, 0);
				test_stop();
			}
			lseek(out, 0, SEEK_SET);
			dispatch_read(out, siz_out, q,
					^(dispatch_data_t cmp, int err_cmp) {
				if (err_cmp) {
					test_errno("dispatch_read", err_cmp, 0);
					test_stop();
				}
				close(out);
				size_t siz_cmp = dispatch_data_get_size(cmp);
				test_sizet("readback size", siz_cmp, siz_out);
				const void *data_buf, *cmp_buf;
				dispatch_data_t data_map, cmp_map;
				data_map = dispatch_data_create_map(data, &data_buf, NULL);
				cmp_map = dispatch_data_create_map(cmp, &cmp_buf, NULL);
				test_long("readback memcmp",
						memcmp(data_buf, cmp_buf, MIN(siz_out, siz_cmp)), 0);
				dispatch_release(cmp_map);
				dispatch_release(data_map);
				dispatch_release(data);
				dispatch_group_leave(g);
			});
		});
	});
	test_group_wait(g);
	dispatch_release(g);
}

static void
test_read_writes(void) // <rdar://problem/7785143>
{
	const char *path_in = "/dev/urandom";
	char path_out[] = "/tmp/dispatchtest_io.XXXXXX";
	const size_t chunks_out = 320;
	const size_t siz_chunk = 32, siz_in = siz_chunk * chunks_out;

	int in = open(path_in, O_RDONLY);
	if (in == -1) {
		test_errno("open", errno, 0);
		test_stop();
	}
	int out = mkstemp(path_out);
	if (out == -1) {
		test_errno("mkstemp", errno, 0);
		test_stop();
	}
	if (unlink(path_out) == -1) {
		test_errno("unlink", errno, 0);
		test_stop();
	}
	dispatch_queue_t q = dispatch_get_global_queue(0,0);
	dispatch_group_t g = dispatch_group_create();
	dispatch_group_enter(g);
	__block dispatch_data_t data;
	__block size_t siz_out;
	dispatch_read(in, siz_in, q, ^(dispatch_data_t data_in, int err_in) {
		if (err_in) {
			test_errno("dispatch_read", err_in, 0);
			test_stop();
		}
		close(in);
		siz_out = dispatch_data_get_size(data_in);
		test_sizet("read size", siz_out, siz_in);
		dispatch_retain(data_in);
		data = data_in;
		dispatch_data_t data_chunks[chunks_out];
		size_t i;
		for (i = 0; i < chunks_out; i++) {
			data_chunks[i] = dispatch_data_create_subrange(data_in,
					i * siz_chunk, siz_chunk);
		}
		for (i = 0; i < chunks_out; i++) {
			dispatch_data_t d = data_chunks[i];
			dispatch_group_enter(g);
			dispatch_write(out, d, q, ^(dispatch_data_t data_out,
					int err_out) {
				if (err_out || data_out) {
					test_errno("dispatch_write", err_out, 0);
					test_stop();
				}
				dispatch_group_leave(g);
			});
		}
		for (i = 0; i < chunks_out; i++) {
			dispatch_release(data_chunks[i]);
		}
		dispatch_group_leave(g);
	});
	test_group_wait(g);
	dispatch_group_enter(g);
	lseek(out, 0, SEEK_SET);
	dispatch_read(out, siz_in, q,
			^(dispatch_data_t cmp, int err_cmp) {
		if (err_cmp) {
			test_errno("dispatch_read", err_cmp, 0);
			test_stop();
		}
		close(out);
		size_t siz_cmp = dispatch_data_get_size(cmp);
		test_sizet("readback size", siz_cmp, siz_out);
		const void *data_buf, *cmp_buf;
		dispatch_data_t data_map, cmp_map;
		data_map = dispatch_data_create_map(data, &data_buf, NULL);
		cmp_map = dispatch_data_create_map(cmp, &cmp_buf, NULL);
		test_long("readback memcmp",
				memcmp(data_buf, cmp_buf, MIN(siz_out, siz_cmp)), 0);
		dispatch_release(cmp_map);
		dispatch_release(data_map);
		dispatch_release(data);
		dispatch_group_leave(g);
	});
	test_group_wait(g);
	dispatch_release(g);
}

static void
test_writes_reads_eagain(void) // rdar://problem/8333366
{
	int in = open("/dev/urandom", O_RDONLY);
	if (in == -1) {
		test_errno("open", errno, 0);
		test_stop();
	}
	int fds[2], *fd = fds;
	if(pipe(fd) == -1) {
		test_errno("pipe", errno, 0);
		test_stop();
	}
	const size_t chunks = 320;
	const size_t siz_chunk = 32, siz = siz_chunk * chunks;

	dispatch_queue_t q = dispatch_get_global_queue(0,0);
	dispatch_group_t g = dispatch_group_create();
	__block size_t siz_acc = 0, deliveries = 0;
	__block void (^b)(dispatch_data_t, int);
	b = Block_copy(^(dispatch_data_t data, int err) {
		if (err) {
			test_errno("dispatch_read", err, 0);
			test_stop();
		}
		deliveries++;
		siz_acc += dispatch_data_get_size(data);
		if (siz_acc < siz) {
			dispatch_group_enter(g);
			dispatch_read(*fd, siz, q, b);
		}
		dispatch_group_leave(g);
	});
	dispatch_group_enter(g);
	dispatch_read(*fd, siz, q, b);
	char *buf[siz_chunk];
	size_t i;
	for (i = 0; i < chunks; i++) {
		ssize_t s = read(in, buf, siz_chunk);
		if (s < (ssize_t)siz_chunk) {
			test_errno("read", errno, 0);
			test_stop();
		}
		s = write(*(fd+1), buf, siz_chunk);
		if (s < (ssize_t)siz_chunk) {
			test_errno("write", errno, 0);
			test_stop();
		}
		usleep(10000);
	}
	close(in);
	close(*(fd+1));
	test_group_wait(g);
	test_sizet("dispatch_read deliveries", deliveries, chunks);
	test_sizet("dispatch_read data size", siz_acc, siz);
	close(*fd);
	Block_release(b);
	dispatch_release(g);
}

#endif // DISPATCHTEST_IO

int
main(void)
{
	dispatch_test_start("Dispatch IO Convenience Read/Write");

	dispatch_async(dispatch_get_main_queue(), ^{
#if DISPATCHTEST_IO
		test_read();
		test_read_write();
		test_read_writes();
		test_writes_reads_eagain();
#endif
		test_fin(NULL);
	});
	dispatch_main();
}
