/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include "os/mynewt.h"
#include "hal/hal_flash.h"
#include "hal/hal_system.h"
#include "testutil/testutil.h"
#include "testutil_priv.h"

/* The test task runs at a lower priority (greater number) than the default
 * task.  This allows the test task to assume events get processed as soon as
 * they are initiated.  The test code can then immediately assert the expected
 * result of event processing.
 */
#define TU_TEST_TASK_PRIO   (MYNEWT_VAL(OS_MAIN_TASK_PRIO) + 1)
#define TU_TEST_STACK_SIZE  1024

struct tu_config tu_config;

int tu_any_failed;

struct ts_testsuite_list *ts_suites;

void
tu_set_pass_cb(tu_case_report_fn_t *cb, void *cb_arg)
{
    tu_config.pass_cb = cb;
    tu_config.pass_arg = cb_arg;
}

void
tu_set_fail_cb(tu_case_report_fn_t *cb, void *cb_arg)
{
    tu_config.fail_cb = cb;
    tu_config.fail_arg = cb_arg;
}

#if MYNEWT_VAL(SELFTEST)
static void
tu_pass_cb_self(const char *msg, void *arg)
{
    printf("[pass] %s/%s %s\n", tu_config.ts_suite_name, tu_case_name, msg);
    fflush(stdout);
}

static void
tu_fail_cb_self(const char *msg, void *arg)
{
    printf("[FAIL] %s/%s %s\n", tu_config.ts_suite_name, tu_case_name, msg);
    fflush(stdout);
}
#endif

void
tu_init(void)
{
    /* Ensure this function only gets called by sysinit. */
    SYSINIT_ASSERT_ACTIVE();

#if MYNEWT_VAL(SELFTEST)
    os_init(NULL);
    tu_set_pass_cb(tu_pass_cb_self, NULL);
    tu_set_fail_cb(tu_fail_cb_self, NULL);
#endif
}

void
tu_arch_restart(void)
{
#if MYNEWT_VAL(SELFTEST)
    os_arch_os_stop();
    tu_case_abort();
#else
    hal_system_reset();
#endif
}

void
tu_restart(void)
{
    tu_case_write_pass_auto();
    tu_arch_restart();
}

static void
tu_dflt_task_handler(void *arg)
{
    while (1) {
        os_eventq_run(os_eventq_dflt_get());
    }
}

static void
tu_create_dflt_task(void)
{
    static os_stack_t stack[OS_STACK_ALIGN(OS_MAIN_STACK_SIZE)];
    static struct os_task task;

    os_task_init(&task, "tu_dflt_task", tu_dflt_task_handler, NULL,
                 OS_MAIN_TASK_PRIO, OS_WAIT_FOREVER, stack,
                 OS_STACK_ALIGN(OS_MAIN_STACK_SIZE));
}

static void
tu_test_task_handler(void *arg)
{
    os_task_func_t fn;

    fn = (os_task_func_t)arg;
    fn(NULL);

    tu_restart();
}

/**
 * Creates the "test task."  For test cases running in the OS, this is the task
 * that contains the actual test logic.
 */
static void
tu_create_test_task(const char *task_name, os_task_func_t task_handler)
{
    static os_stack_t stack[OS_STACK_ALIGN(TU_TEST_STACK_SIZE)];
    static struct os_task task;

    os_task_init(&task, task_name, tu_test_task_handler, (void *)task_handler,
                 TU_TEST_TASK_PRIO, OS_WAIT_FOREVER, stack,
                 OS_STACK_ALIGN(TU_TEST_STACK_SIZE));

    os_start();
}

/**
 * Creates the default task, creates the test task to run a test case in, and
 * starts the OS.
 */
void
tu_start_os(const char *test_task_name, os_task_func_t test_task_handler)
{
    tu_create_dflt_task();
    tu_create_test_task(test_task_name, test_task_handler);

    os_start();
}
