/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

/* Include Kconfig variables. */
#include <autoconf.h>
#include <sel4test-driver/gen_config.h>

#include <assert.h>
#include <stdio.h>

/* Our headers are not C++ friendly */
extern "C" {

#include <sel4/sel4.h>

#include "../helpers.h"

}

#define POLL_DELAY_NS 4000000

typedef int (*test_func_t)(seL4_Word /* id */, env_t env /* env */);

static int
own_domain_success(struct env *env)
{
    int error;

    error = seL4_DomainSet_Set(env->domain, CONFIG_NUM_DOMAINS - 1,
                               env->tcb);
    return (error == seL4_NoError) ? SUCCESS : FAILURE;
}

static int
own_domain_baddom(struct env *env)
{
    int error;

    error = seL4_DomainSet_Set(env->domain, CONFIG_NUM_DOMAINS + 10,
                               env->tcb);
    return (error == seL4_InvalidArgument) ? SUCCESS : FAILURE;
}

static int
own_domain_badcap(struct env *env)
{
    int error;

    error = seL4_DomainSet_Set(env->tcb, 0,
                               env->tcb);
    return (error == seL4_IllegalOperation) ? SUCCESS : FAILURE;
}

int fdom1(seL4_Word id, env_t env)
{
    int countdown = 50;

    while (countdown > 0) {
        sleep_busy(env, POLL_DELAY_NS);
        --countdown;
        ZF_LOGD("%2d, ", (int)id);
    }

    return sel4test_get_result();
}

/* This is a very simple (and rather stupid) C++ usage. Proves that a template
 * can be defined but is not good C++ */
template<bool shift, typename F>
static int
test_domains(struct env *env, F func)
{

    UNUSED int error;
    helper_thread_t thread[CONFIG_NUM_DOMAINS];

    for (int i = 0; i < CONFIG_NUM_DOMAINS; ++i) {
        create_helper_thread(env, &thread[i]);
        set_helper_priority(env, &thread[i], 64);
        error = seL4_DomainSet_Set(env->domain, (seL4_Word)i, get_helper_tcb(&thread[i]));
        assert(error == seL4_NoError);
    }

    for (int i = 0; i < CONFIG_NUM_DOMAINS; ++i) {
        start_helper(env, &thread[i], (helper_fn_t) func, i, (seL4_Word) env, 0, 0);
    }

    if (CONFIG_NUM_DOMAINS > 1 && shift) {
        sel4test_sleep(env, POLL_DELAY_NS * 2);
        error = seL4_DomainSet_Set(env->domain, CONFIG_NUM_DOMAINS - 1, get_helper_tcb(&thread[0]));
        assert(error == seL4_NoError);
    }

    for (int i = 0; i < CONFIG_NUM_DOMAINS; ++i) {
        wait_for_helper(&thread[i]);
        cleanup_helper(env, &thread[i]);
    }

    return sel4test_get_result();
}

/* The output from this test should show alternating "domain blocks", with,
 * within each, a single thread printing. For example:
 *
 * 00, 00, ..., 00, 01, 01, ..., 01, 00, 00, ..., 00, 01, 01, ..., 01, etc.
 * +-------------+  +-------------+  +-------------+  +-------------+
 *  block 0           block 1          block 0          block 1
 */
static int
test_run_domains(struct env* env)
{
    return test_domains<false>(env, fdom1);
}
DEFINE_TEST(DOMAINS0004, "Run threads in domains()", test_run_domains, config_set(CONFIG_HAVE_TIMER))

/* The output of this test differs from that of DOMAINS0004 in that the thread
 * in domain 0 is moved into domain 1 after a short delay. This should be
 * visible in the output, where the "domain block" for domain 1 should contain
 * the alternating output of threads 0 and 1. For example:
 *
 * 00, 00, ..., 00, 01, 00, 01, 00, ..., 01, 01, 01, 01
 * +-------------+  +------------------+ +------------+
 *  initial block    alterations           final block
 *  (due to delay)   (after shift)         (01 catches up)
 */
static int
test_run_domains_shift(struct env* env)
{
    return test_domains<true>(env, fdom1);
}
DEFINE_TEST(DOMAINS0005, "Move thread between domains()", test_run_domains_shift, config_set(CONFIG_HAVE_TIMER) && CONFIG_NUM_DOMAINS > 1)

static int
test_own_domain1(struct env* env)
{
    return own_domain_success(env);
}
DEFINE_TEST(DOMAINS0001, "Change domain successfully()", test_own_domain1, true)

static int
test_own_domain2(struct env* env)
{
    return own_domain_baddom(env);
}
DEFINE_TEST(DOMAINS0002, "Try non-existant domain()", test_own_domain2, true)

static int
test_own_domain3(struct env* env)
{
    return own_domain_badcap(env);
}
DEFINE_TEST(DOMAINS0003, "Invoke non-domain cap()", test_own_domain3, true)
