/*
 * 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 <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <dispatch/dispatch.h>

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

static ssize_t actual;

void stage1(int stage);
void stage2(void);
void finish(void* cxt);

void
stage1(int stage)
{
#if defined(_WIN32)
	char *path = dispatch_test_get_large_file();
	dispatch_fd_t fd = dispatch_test_fd_open(path, O_RDONLY);
	if (fd == -1)
	{
		perror(path);
		exit(EXIT_FAILURE);
	}
	dispatch_test_release_large_file(path);
	free(path);
#else
	const char *path = "/dev/random";
	int fd = open(path, O_RDONLY);
	if (fd == -1)
	{
		perror(path);
		exit(EXIT_FAILURE);
	}
#endif

	dispatch_queue_t main_q = dispatch_get_main_queue();
	test_ptr_notnull("main_q", main_q);

	dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t)fd, 0, main_q);
	test_ptr_notnull("select source", source);

	dispatch_source_set_event_handler(source, ^{
		size_t buffer_size = 500*1024;
		char buffer[500*1024];
		ssize_t sz = dispatch_test_fd_read(fd, buffer, buffer_size);
		test_sizet_less_than_or_equal("kevent read 1", sz, buffer_size+1);
		dispatch_source_cancel(source);
	});

	dispatch_source_set_cancel_handler(source, ^{
		int res = dispatch_test_fd_close(fd);
		test_errno("close", res ==  -1 ? errno : 0, 0);
		dispatch_release(source);
		if (stage == 1)
		{
			dispatch_async(dispatch_get_main_queue(), ^{
				stage2();
			});
		}
	});

	if (stage == 3)
	{
		dispatch_set_context(source, source);
		dispatch_set_finalizer_f(source, finish);
	}

	dispatch_resume(source);
}

void
stage2(void)
{
	char *path = dispatch_test_get_large_file();
	dispatch_fd_t fd = dispatch_test_fd_open(path, O_RDONLY);
	if (fd == -1)
	{
		perror(path);
		exit(EXIT_FAILURE);
	}
	dispatch_test_release_large_file(path);
	free(path);

	if (!dispatch_test_check_evfilt_read_for_fd(fd)) {
		test_skip("EVFILT_READ kevent not firing for test file");
		dispatch_test_fd_close(fd);
		dispatch_async(dispatch_get_main_queue(), ^{
			stage1(3);
		});
		return;
	}

	ssize_t expected = dispatch_test_fd_lseek(fd, 0, SEEK_END);
	dispatch_test_fd_lseek(fd, 0, SEEK_SET);
	actual = 0;

	dispatch_queue_t main_q = dispatch_get_main_queue();
	test_ptr_notnull("main_q", main_q);

	dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, (uintptr_t)fd, 0, main_q);
	test_ptr_notnull("kevent source", source);

	dispatch_source_set_event_handler(source, ^{
		size_t est = dispatch_source_get_data(source);
		test_sizet_less_than_or_equal("estimated", est, expected - actual);
		char buffer[500*1024];
		ssize_t sz = dispatch_test_fd_read(fd, buffer, sizeof(buffer));
		actual += sz;
		if (sz < (ssize_t)sizeof(buffer))
		{
			sz = dispatch_test_fd_read(fd, buffer, sizeof(buffer));
			actual += sz;
			test_long("EOF", sz, 0);
			dispatch_source_cancel(source);
		}
	});

	dispatch_source_set_cancel_handler(source, ^{
		test_long("bytes read", actual, expected);
		int res = dispatch_test_fd_close(fd);
		test_errno("close", res ==  -1 ? errno : 0, 0);
		dispatch_release(source);
		dispatch_async(dispatch_get_main_queue(), ^{
			stage1(3);
		});
	});

	dispatch_resume(source);
}

void
finish(void* cxt)
{
	test_ptr("finish", cxt, cxt);
	test_stop();
}

int
main(void)
{
	dispatch_test_start("Dispatch select workaround test"); // <rdar://problem/7678012>

	dispatch_async(dispatch_get_main_queue(), ^{
		stage1(1);
	});

	dispatch_main();
}
