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

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

#if DISPATCH_API_VERSION >= 20100825 && DISPATCH_API_VERSION != 20101110

static char *ctxts[] = {"ctxt for app", "ctxt for key 1",
		"ctxt for key 2", "ctxt for key 1 bis", "ctxt for key 4"};
volatile long ctxts_destroyed;
static dispatch_group_t g;

static void
destructor(void *ctxt)
{
	fprintf(stderr, "destructor of %s\n", (char*)ctxt);
	(void)__sync_add_and_fetch(&ctxts_destroyed, 1);
	dispatch_group_leave(g);
}

static void
test_context_for_key(void)
{
	g = dispatch_group_create();
	dispatch_queue_t q = dispatch_queue_create("q", NULL);
#if DISPATCH_API_VERSION >= 20100518
	dispatch_queue_t tq = dispatch_queue_create("tq", DISPATCH_QUEUE_CONCURRENT);
#else
	dispatch_queue_t tq = dispatch_queue_create("tq", NULL);
	dispatch_queue_set_width(tq, LONG_MAX);
#endif
	dispatch_queue_t ttq = dispatch_get_global_queue(0, 0);
	dispatch_group_enter(g);
#if DISPATCH_API_VERSION >= 20101011
	dispatch_queue_set_specific(tq, &ctxts[4], ctxts[4], destructor);
#else
	dispatch_set_context_for_key(tq, &ctxts[4], ctxts[4], ttq, destructor);
#endif
	dispatch_set_target_queue(tq, ttq);
	dispatch_group_enter(g);
	dispatch_set_context(q, ctxts[0]);
	dispatch_set_target_queue(q, tq);
	dispatch_set_finalizer_f(q, destructor);

	dispatch_async(q, ^{
		dispatch_group_enter(g);
#if DISPATCH_API_VERSION >= 20101011
		dispatch_queue_set_specific(q, &ctxts[1], ctxts[1], destructor);
#else
		dispatch_set_context_for_key(q, &ctxts[1], ctxts[1], ttq, destructor);
#endif
	});
	dispatch_retain(q);
	dispatch_async(dispatch_get_global_queue(0, 0), ^{
		dispatch_group_enter(g);
#if DISPATCH_API_VERSION >= 20101011
		dispatch_queue_set_specific(q, &ctxts[2], ctxts[2], destructor);
#else
		dispatch_set_context_for_key(q, &ctxts[2], ctxts[2], ttq, destructor);
#endif
		dispatch_async(dispatch_get_global_queue(0, 0), ^{
			void *ctxt;
#if DISPATCH_API_VERSION >= 20101011
			ctxt = dispatch_queue_get_specific(q, &ctxts[2]);
#else
			ctxt = dispatch_get_context_for_key(q, &ctxts[2]);
#endif
			test_ptr("get context for key 2", ctxt, ctxts[2]);
			dispatch_release(q);
		});
	});
	dispatch_async(q, ^{
		void *ctxt;
#if DISPATCH_API_VERSION >= 20101011
		ctxt = dispatch_get_specific(&ctxts[1]);
		test_ptr("get current context for key 1", ctxt, ctxts[1]);
		ctxt = dispatch_get_specific(&ctxts[4]);
		test_ptr("get current context for key 4 (on target queue)", ctxt, ctxts[4]);
		ctxt = dispatch_queue_get_specific(q, &ctxts[1]);
#else
		ctxt = dispatch_get_context_for_key(tq, &ctxts[4]);
		test_ptr("get context for key 4 (on target queue)", ctxt, ctxts[4]);
		ctxt = dispatch_get_context_for_key(q, &ctxts[1]);
#endif
		test_ptr("get context for key 1", ctxt, ctxts[1]);
	});
	dispatch_async(q, ^{
		dispatch_group_enter(g);
		void *ctxt;
#if DISPATCH_API_VERSION >= 20101011
		dispatch_queue_set_specific(q, &ctxts[1], ctxts[3], destructor);
		ctxt = dispatch_queue_get_specific(q, &ctxts[1]);
#else
		dispatch_set_context_for_key(q, &ctxts[1], ctxts[3], ttq, destructor);
		ctxt = dispatch_get_context_for_key(q, &ctxts[1]);
#endif
		test_ptr("get context for key 1", ctxt, ctxts[3]);
	});
	dispatch_async(q, ^{
		void *ctxt;
#if DISPATCH_API_VERSION >= 20101011
		dispatch_queue_set_specific(q, &ctxts[1], NULL, destructor);
		ctxt = dispatch_queue_get_specific(q, &ctxts[1]);
#else
		dispatch_set_context_for_key(q, &ctxts[1], NULL, ttq, destructor);
		ctxt = dispatch_get_context_for_key(q, &ctxts[1]);
#endif
		test_ptr("get context for key 1", ctxt, NULL);
	});
	void *ctxt = dispatch_get_context(q);
	test_ptr("get context for app", ctxt, ctxts[0]);
	dispatch_release(tq);
	dispatch_release(q);
	dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
	test_long("contexts destroyed", ctxts_destroyed, 5);
	dispatch_release(g);
}
#endif

int
main(void)
{
	dispatch_test_start("Dispatch Queue Specific"); // rdar://problem/8429188

	dispatch_async(dispatch_get_main_queue(), ^{
#if DISPATCH_API_VERSION >= 20100825 && DISPATCH_API_VERSION != 20101110
		test_context_for_key();
#endif
		test_stop();
	});
	dispatch_main();
}
