/*
 * Copyright (c) 2008-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 <dispatch/dispatch.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#ifdef __APPLE__
#include <libkern/OSAtomic.h>
#endif
#include <math.h>
#include <bsdtests.h>
#include "dispatch_test.h"

#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC 1000000000
#endif

#if TARGET_OS_EMBEDDED
#define LOOP_COUNT 50000
#else
#define LOOP_COUNT 200000
#endif

static void test_group_notify(void*);

static dispatch_group_t
create_group(size_t count, unsigned int delay)
{
	size_t i;

	dispatch_group_t group = dispatch_group_create();

	for (i = 0; i < count; ++i) {
		dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
		assert(queue);

		dispatch_group_async(group, queue, ^{
			if (delay) {
				fprintf(stderr, "sleeping...\n");
				sleep(delay);
				fprintf(stderr, "done.\n");
			}
		});

		dispatch_release(queue);
		}
	return group;
}

static void
test_group(void *ctxt __attribute__((unused)))
{
	long res;
	dispatch_group_t group;

	group = create_group(100, 0);
	test_ptr_notnull("dispatch_group_async", group);

	dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

	// should be OK to re-use a group
	dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{});
	dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

	dispatch_release(group);
	group = NULL;

	group = create_group(3, 7);
	test_ptr_notnull("dispatch_group_async", group);

	res = dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 5ull * NSEC_PER_SEC));
	test_long("dispatch_group_wait", !res, 0);

	// retry after timeout (this time succeed)
	res = dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 5ull * NSEC_PER_SEC));
	test_long("dispatch_group_wait", res, 0);

	dispatch_release(group);
	group = NULL;

	group = create_group(100, 0);
	test_ptr_notnull("dispatch_group_async", group);

	dispatch_group_notify(group, dispatch_get_main_queue(), ^{
		dispatch_test_current("Notification Received", dispatch_get_main_queue());
		dispatch_async_f(dispatch_get_main_queue(), NULL, test_group_notify);
	});

	dispatch_release(group);
	group = NULL;
}

static long completed;

static void
test_group_notify2(long cycle, dispatch_group_t tested)
{
	static dispatch_queue_t rq, nq;
	static dispatch_once_t once;
	dispatch_once(&once, ^{
		rq = dispatch_queue_create("release", 0);
		dispatch_suspend(rq);
		nq = dispatch_queue_create("notify", 0);
	});
	dispatch_resume(rq);

	// n=4 works great for a 4CPU Mac Pro, this might work for a wider range of
	// systems.
#if HAVE_ARC4RANDOM
	const int n = 1 + arc4random() % 8;
#else
    const int n = 1 + random() % 8;
#endif
	dispatch_group_t group = dispatch_group_create();
	dispatch_queue_t qa[n];

	dispatch_group_enter(group);
	for (int i = 0; i < n; i++) {
		char buf[48];
		sprintf(buf, "T%ld-%d", cycle, i);
		qa[i] = dispatch_queue_create(buf, 0);
	}

	__block float eh = 0;
	for (int i = 0; i < n; i++) {
		dispatch_queue_t q = qa[i];
		dispatch_group_async(group, q, ^{
			// Seems to trigger a little more reliably with some work being
			// done in this block
			assert(cycle && "cycle must be non-zero");
			eh = (float)sin(M_1_PI / cycle);
		});
	}
	dispatch_group_leave(group);

	dispatch_group_notify(group, nq, ^{
		completed = cycle;
		dispatch_group_leave(tested);
	});

	// Releasing qa's queues here seems to avoid the race, so we are arranging
	// for the current iteration's queues to be released on the next iteration.
	dispatch_sync(rq, ^{});
	dispatch_suspend(rq);
	for (int i = 0; i < n; i++) {
		dispatch_queue_t q = qa[i];
		dispatch_async(rq, ^{ dispatch_release(q); });
	}
	dispatch_release(group);
}

static void
test_group_notify(void *ctxt __attribute__((unused)))
{
	// <rdar://problem/11445820>
	dispatch_group_t tested = dispatch_group_create();
	test_ptr_notnull("dispatch_group_create", tested);
	long i;
	for (i = 1; i <= LOOP_COUNT; i++) {
		if (!(i % (LOOP_COUNT/10))) {
			fprintf(stderr, "#%ld\n", i);
		}
		dispatch_group_enter(tested);
		test_group_notify2(i, tested);
		if (dispatch_group_wait(tested, dispatch_time(DISPATCH_TIME_NOW,
				NSEC_PER_SEC))) {
			break;
		}
	}
	test_long("dispatch_group_notify", i - 1, LOOP_COUNT);
	test_stop();
}

int
main(void)
{
	dispatch_test_start("Dispatch Group");
	dispatch_async_f(dispatch_get_main_queue(), NULL, test_group);
	dispatch_main();

	return 0;
}
