// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2008-2014 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

/**
 * @defgroup debug  Debug
 * @{
 */

/**
 * @file
 * @brief  Debug console functions.
 */

#include <debug.h>
#include <err.h>
#include <inttypes.h>
#include <kernel/mp.h>
#include <kernel/percpu.h>
#include <kernel/thread.h>
#include <kernel/timer.h>
#include <platform.h>
#include <stdio.h>
#include <string.h>
#include <vm/vm.h>
#include <zircon/types.h>

#if WITH_LIB_CONSOLE
#include <lib/console.h>

static int cmd_thread(int argc, const cmd_args* argv, uint32_t flags);
static int cmd_threadstats(int argc, const cmd_args* argv, uint32_t flags);
static int cmd_threadload(int argc, const cmd_args* argv, uint32_t flags);
static int cmd_kill(int argc, const cmd_args* argv, uint32_t flags);

STATIC_COMMAND_START
#if LK_DEBUGLEVEL > 1
STATIC_COMMAND_MASKED("thread", "list kernel threads with options", &cmd_thread, CMD_AVAIL_ALWAYS)
#endif
STATIC_COMMAND("threadstats", "thread level statistics", &cmd_threadstats)
STATIC_COMMAND("threadload", "toggle thread load display", &cmd_threadload)
STATIC_COMMAND("kill", "kill a thread", &cmd_kill)
STATIC_COMMAND_END(kernel);

#if LK_DEBUGLEVEL > 1
static int cmd_thread(int argc, const cmd_args* argv, uint32_t flags) {

    if (argc < 2) {
    notenoughargs:
        printf("not enough arguments\n");
    usage:
        printf("%s dump <thread pointer or id>\n", argv[0].str);
        printf("%s list\n", argv[0].str);
        printf("%s list_full\n", argv[0].str);
        return -1;
    }

    if (!strcmp(argv[1].str, "dump")) {
        if (argc < 3)
            goto notenoughargs;

        thread_t* t = NULL;
        if (is_kernel_address(argv[2].u)) {
            t = (thread_t *)argv[2].u;
            dump_thread(t, true);
        } else {
            if (flags & CMD_FLAG_PANIC) {
                dump_thread_user_tid_locked(argv[2].u, true);
            } else {
                dump_thread_user_tid(argv[2].u, true);
            }
        }
    } else if (!strcmp(argv[1].str, "list")) {
        printf("thread list:\n");
        if (flags & CMD_FLAG_PANIC) {
            dump_all_threads_locked(false);
        } else {
            dump_all_threads(false);
        }
    } else if (!strcmp(argv[1].str, "list_full")) {
        printf("thread list:\n");
        if (flags & CMD_FLAG_PANIC) {
            dump_all_threads_locked(true);
        } else {
            dump_all_threads(true);
        }
    } else {
        printf("invalid args\n");
        goto usage;
    }

    /* reschedule to let debuglog potentially run */
    if (!(flags & CMD_FLAG_PANIC))
        thread_reschedule();

    return 0;
}
#endif

static int cmd_threadstats(int argc, const cmd_args* argv, uint32_t flags) {
    for (uint i = 0; i < SMP_MAX_CPUS; i++) {
        if (!mp_is_cpu_active(i))
            continue;

        printf("thread stats (cpu %u):\n", i);
        printf("\ttotal idle time: %" PRIu64 "\n", percpu[i].stats.idle_time);
        printf("\ttotal busy time: %" PRIu64 "\n",
               current_time() - percpu[i].stats.idle_time);
        printf("\treschedules: %lu\n", percpu[i].stats.reschedules);
        printf("\treschedule_ipis: %lu\n", percpu[i].stats.reschedule_ipis);
        printf("\tcontext_switches: %lu\n", percpu[i].stats.context_switches);
        printf("\tpreempts: %lu\n", percpu[i].stats.preempts);
        printf("\tyields: %lu\n", percpu[i].stats.yields);
        printf("\tinterrupts: %lu\n", percpu[i].stats.interrupts);
        printf("\ttimer interrupts: %lu\n", percpu[i].stats.timer_ints);
        printf("\ttimers: %lu\n", percpu[i].stats.timers);
    }

    return 0;
}

static enum handler_return threadload(struct timer* t, zx_time_t now, void* arg) {
    static struct cpu_stats old_stats[SMP_MAX_CPUS];
    static zx_duration_t last_idle_time[SMP_MAX_CPUS];

    printf("cpu    load"
           " sched (cs ylds pmpts irq_pmpts)"
           " excep"
           "    pf"
           "  sysc"
           " ints (hw  tmr tmr_cb)"
           " ipi (rs  gen)\n");
    for (uint i = 0; i < SMP_MAX_CPUS; i++) {
        /* dont display time for inactive cpus */
        if (!mp_is_cpu_active(i))
            continue;

        zx_duration_t idle_time = percpu[i].stats.idle_time;

        /* if the cpu is currently idle, add the time since it went idle up until now to the idle counter */
        bool is_idle = !!mp_is_cpu_idle(i);
        if (is_idle) {
            idle_time += current_time() - percpu[i].idle_thread.last_started_running;
        }

        zx_duration_t delta_time = idle_time - last_idle_time[i];
        zx_duration_t busy_time = ZX_SEC(1) - (delta_time > ZX_SEC(1) ? ZX_SEC(1) : delta_time);
        uint busypercent = (busy_time * 10000) / ZX_SEC(1);

        printf("%3u"
               " %3u.%02u%%"
               " %9lu %4lu %5lu %9lu"
               " %6lu"
               " %5lu"
               " %5lu"
               " %8lu %4lu %6lu"
               " %8lu %4lu"
               "\n",
               i,
               busypercent / 100, busypercent % 100,
               percpu[i].stats.context_switches - old_stats[i].context_switches,
               percpu[i].stats.yields - old_stats[i].yields,
               percpu[i].stats.preempts - old_stats[i].preempts,
               percpu[i].stats.irq_preempts - old_stats[i].irq_preempts,
               percpu[i].stats.exceptions - old_stats[i].exceptions,
               percpu[i].stats.page_faults - old_stats[i].page_faults,
               percpu[i].stats.syscalls - old_stats[i].syscalls,
               percpu[i].stats.interrupts - old_stats[i].interrupts,
               percpu[i].stats.timer_ints - old_stats[i].timer_ints,
               percpu[i].stats.timers - old_stats[i].timers,
               percpu[i].stats.reschedule_ipis - old_stats[i].reschedule_ipis,
               percpu[i].stats.generic_ipis - old_stats[i].generic_ipis);

        old_stats[i] = percpu[i].stats;
        last_idle_time[i] = idle_time;
    }

    timer_set(t, now + ZX_SEC(1), TIMER_SLACK_CENTER, ZX_MSEC(10), &threadload, NULL);

    /* reschedule here to allow the debuglog a chance to run */
    return INT_RESCHEDULE;
}

static int cmd_threadload(int argc, const cmd_args* argv, uint32_t flags) {
    static bool showthreadload = false;
    static timer_t tltimer;

    if (showthreadload == false) {
        // start the display
        timer_init(&tltimer);
        timer_set(&tltimer, current_time() + ZX_SEC(1),
                  TIMER_SLACK_CENTER, ZX_MSEC(10), &threadload, NULL);
        showthreadload = true;
    } else {
        timer_cancel(&tltimer);
        showthreadload = false;
    }

    return 0;
}

static int cmd_kill(int argc, const cmd_args* argv, uint32_t flags) {
    if (argc < 2) {
        printf("not enough arguments\n");
        return -1;
    }

    bool wait = true;
    if (argc >= 3 && !strcmp(argv[2].str, "nowait"))
        wait = false;
    thread_kill(argv[1].p, wait);

    return 0;
}

#endif // WITH_LIB_CONSOLE
