/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Test hooks.
 */

#include "common.h"
#include "console.h"
#include "hooks.h"
#include "test_util.h"
#include "timer.h"
#include "util.h"

static int init_hook_count;
static int tick_hook_count;
static int tick2_hook_count;
static int tick_count_seen_by_tick2;
static timestamp_t tick_time[2];
static int second_hook_count;
static timestamp_t second_time[2];
static int deferred_call_count;

static void init_hook(void)
{
	init_hook_count++;
}
DECLARE_HOOK(HOOK_INIT, init_hook, HOOK_PRIO_DEFAULT);

static void tick_hook(void)
{
	tick_hook_count++;
	tick_time[0] = tick_time[1];
	tick_time[1] = get_time();
}
DECLARE_HOOK(HOOK_TICK, tick_hook, HOOK_PRIO_DEFAULT);

static void tick2_hook(void)
{
	tick2_hook_count++;
	tick_count_seen_by_tick2 = tick_hook_count;
}
/* tick2_hook() prio means it should be called after tick_hook() */
DECLARE_HOOK(HOOK_TICK, tick2_hook, HOOK_PRIO_DEFAULT+1);

static void second_hook(void)
{
	second_hook_count++;
	second_time[0] = second_time[1];
	second_time[1] = get_time();
}
DECLARE_HOOK(HOOK_SECOND, second_hook, HOOK_PRIO_DEFAULT);

static void deferred_func(void)
{
	deferred_call_count++;
}
DECLARE_DEFERRED(deferred_func);

static void non_deferred_func(void)
{
	deferred_call_count++;
}

static const struct deferred_data non_deferred_func_data = {
	non_deferred_func
};

static int test_init_hook(void)
{
	TEST_ASSERT(init_hook_count == 1);
	return EC_SUCCESS;
}

static int test_ticks(void)
{
	int64_t interval;
	int error_pct;

	/*
	 * HOOK_SECOND must have been fired at least once when HOOK
	 * task starts. We only need to wait for just more than a second
	 * to allow it fires for the second time.
	 */
	usleep(1300 * MSEC);

	interval = tick_time[1].val - tick_time[0].val;
	error_pct = (interval - HOOK_TICK_INTERVAL) * 100 /
		    HOOK_TICK_INTERVAL;
	TEST_ASSERT_ABS_LESS(error_pct, 10);

	interval = second_time[1].val - second_time[0].val;
	error_pct = (interval - SECOND) * 100 / SECOND;
	TEST_ASSERT_ABS_LESS(error_pct, 10);

	return EC_SUCCESS;
}

static int test_priority(void)
{
	usleep(HOOK_TICK_INTERVAL);
	TEST_ASSERT(tick_hook_count == tick2_hook_count);
	TEST_ASSERT(tick_hook_count == tick_count_seen_by_tick2);

	return EC_SUCCESS;
}

static int test_deferred(void)
{
	deferred_call_count = 0;
	hook_call_deferred(&deferred_func_data, 50 * MSEC);
	usleep(100 * MSEC);
	TEST_ASSERT(deferred_call_count == 1);

	hook_call_deferred(&deferred_func_data, 50 * MSEC);
	usleep(25 * MSEC);
	hook_call_deferred(&deferred_func_data, -1);
	usleep(75 * MSEC);
	TEST_ASSERT(deferred_call_count == 1);

	hook_call_deferred(&deferred_func_data, 50 * MSEC);
	usleep(25 * MSEC);
	hook_call_deferred(&deferred_func_data, -1);
	usleep(15 * MSEC);
	hook_call_deferred(&deferred_func_data, 25 * MSEC);
	usleep(50 * MSEC);
	TEST_ASSERT(deferred_call_count == 2);

	TEST_ASSERT(hook_call_deferred(&non_deferred_func_data, 50 * MSEC) !=
		    EC_SUCCESS);
	usleep(100 * MSEC);
	TEST_ASSERT(deferred_call_count == 2);

	return EC_SUCCESS;
}

void run_test(void)
{
	test_reset();

	RUN_TEST(test_init_hook);
	RUN_TEST(test_ticks);
	RUN_TEST(test_priority);
	RUN_TEST(test_deferred);

	test_print_result();
}
