// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <threads.h>
#include <unistd.h>

#include <launchpad/launchpad.h>
#include <launchpad/loader-service.h>
#include <zircon/dlfcn.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/status.h>

#include <fdio/util.h>

#include "devmgr.h"
#include "memfs-private.h"

// When adding VMOs to the boot filesystem, add them under the directory
// /boot/VMO_SUBDIR. This constant must end, but not start, with a slash.
#define VMO_SUBDIR "kernel/"
#define VMO_SUBDIR_LEN (sizeof(VMO_SUBDIR) - 1)

// The handle used to transmit messages to appmgr.
static zx_handle_t svc_root_handle;
// The handle used by appmgr to serve incoming requests.
// If appmgr cannot be launched within a timeout, this handle is closed.
static zx_handle_t svc_request_handle;

zx_handle_t get_service_root(void) {
    return fdio_service_clone(svc_root_handle);
}

bool getenv_bool(const char* key, bool _default) {
    const char* value = getenv(key);
    if (value == NULL) {
        return _default;
    }
    if ((strcmp(value, "0") == 0) ||
        (strcmp(value, "false") == 0) ||
        (strcmp(value, "off") == 0)) {
        return false;
    }
    return true;
}

static zx_handle_t root_resource_handle;
static zx_handle_t root_job_handle;
static zx_handle_t svcs_job_handle;
static zx_handle_t fuchsia_job_handle;

zx_handle_t virtcon_open;

zx_handle_t get_root_resource(void) {
    return root_resource_handle;
}

zx_handle_t get_sysinfo_job_root(void) {
    zx_handle_t h;
    //TODO: limit to enumerate rights
    if (zx_handle_duplicate(root_job_handle, ZX_RIGHT_SAME_RIGHTS, &h) < 0) {
        return ZX_HANDLE_INVALID;
    } else {
        return h;
    }
}

static const char* argv_sh[] = { "/boot/bin/sh" };
static const char* argv_autorun0[] = { "/boot/bin/sh", "/boot/autorun" };
static const char* argv_appmgr[] = { "/system/bin/appmgr" };

void do_autorun(const char* name, const char* env) {
    char* bin = getenv(env);
    if (bin) {
        printf("devmgr: %s: starting %s...\n", env, bin);
        devmgr_launch(svcs_job_handle, name,
                      1, (const char* const*) &bin,
                      NULL, -1, NULL, NULL, 0, NULL);
    }
}

static mtx_t appmgr_lock = MTX_INIT;

int devmgr_start_appmgr(void* arg) {
    static bool appmgr_started = false;
    static bool autorun_started = false;

    // we're starting the appmgr because /system is present
    // so we also signal the device coordinator that those
    // drivers are now loadable
    load_system_drivers();

    mtx_lock(&appmgr_lock);
    struct stat s;
    if (!appmgr_started && stat(argv_appmgr[0], &s) == 0) {
        unsigned int appmgr_hnd_count = 0;
        zx_handle_t appmgr_hnds[2] = {};
        uint32_t appmgr_ids[2] = {};
        if (svc_request_handle) {
            assert(appmgr_hnd_count < countof(appmgr_hnds));
            appmgr_hnds[appmgr_hnd_count] = svc_request_handle;
            appmgr_ids[appmgr_hnd_count] = PA_SERVICE_REQUEST;
            appmgr_hnd_count++;
            svc_request_handle = ZX_HANDLE_INVALID;
        }
        devmgr_launch(fuchsia_job_handle, "appmgr", countof(argv_appmgr),
                      argv_appmgr, NULL, -1, appmgr_hnds, appmgr_ids,
                      appmgr_hnd_count, NULL);
        appmgr_started = true;
    }
    if (!autorun_started) {
        do_autorun("autorun:system", "zircon.autorun.system");
        autorun_started = true;
    }
    mtx_unlock(&appmgr_lock);
    return 0;
}

int service_timeout(void* arg) {
    zx_nanosleep(zx_deadline_after(ZX_SEC(10)));
    mtx_lock(&appmgr_lock);
    if (svc_request_handle != ZX_HANDLE_INVALID) {
        printf("devmgr: appmgr not found, closing service handle\n");
        zx_handle_close(svc_request_handle);
    }
    mtx_unlock(&appmgr_lock);
    return 0;
}

int service_starter(void* arg) {
    // create a directory for sevice rendezvous
    mkdir("/svc", 0755);

    char vcmd[64];
    bool netboot = false;
    bool vruncmd = false;

    if (!getenv_bool("netsvc.disable", false)) {
        const char* args[] = { "/boot/bin/netsvc", NULL, NULL };
        int argc = 1;

        if (getenv_bool("netsvc.netboot", false)) {
            args[argc++] = "--netboot";
            netboot = true;
            vruncmd = true;
        }

        const char* nodename = getenv("zircon.nodename");
        if (nodename) {
            args[argc++] = nodename;
        }

        zx_handle_t proc;
        if (devmgr_launch(svcs_job_handle, "netsvc", argc, args,
                          NULL, -1, NULL, NULL, 0, &proc) == ZX_OK) {
            if (vruncmd) {
                zx_info_handle_basic_t info = {
                    .koid = 0,
                };
                zx_object_get_info(proc, ZX_INFO_HANDLE_BASIC,
                                   &info, sizeof(info), NULL, NULL);
                zx_handle_close(proc);
                snprintf(vcmd, sizeof(vcmd), "dlog -f -t -p %zu", info.koid);
            }
        } else {
            vruncmd = false;
        }
    }

    if (!getenv_bool("virtcon.disable", false)) {
        // pass virtcon.* options along
        const char* envp[16];
        unsigned envc = 0;
        char** e = environ;
        while (*e && (envc < countof(envp))) {
            if (!strncmp(*e, "virtcon.", 8)) {
                envp[envc++] = *e;
            }
            e++;
        }
        envp[envc] = NULL;

        uint32_t type = PA_HND(PA_USER0, 0);
        zx_handle_t h = ZX_HANDLE_INVALID;
        zx_channel_create(0, &h, &virtcon_open);
        const char* args[] = { "/boot/bin/virtual-console", "--run", vcmd };
        devmgr_launch(svcs_job_handle, "virtual-console",
                      vruncmd ? 3 : 1, args, envp, -1,
                      &h, &type, (h == ZX_HANDLE_INVALID) ? 0 : 1, NULL);
    }


    do_autorun("autorun:boot", "zircon.autorun.boot");
    struct stat s;
    if (stat(argv_autorun0[1], &s) == 0) {
        printf("devmgr: starting /boot/autorun ...\n");
        devmgr_launch(svcs_job_handle, "sh:autorun0",
                      countof(argv_autorun0), argv_autorun0,
                      NULL, -1, NULL, NULL, 0, NULL);
    }

    if (!netboot) {
        block_device_watcher(svcs_job_handle);
    }
    return 0;
}

#if !_ZX_KERNEL_HAS_SHELL
static int console_starter(void* arg) {
    // if no kernel shell on serial uart, start a sh there
    printf("devmgr: shell startup\n");

    // If we got a TERM environment variable (aka a TERM=... argument on
    // the kernel command line), pass this down.
    const char* term = getenv("TERM");
    if (term != NULL)
        term -= sizeof("TERM=") - 1;

    const char* envp[] = { term ? term : NULL, NULL, };
    for (unsigned n = 0; n < 30; n++) {
        int fd;
        if ((fd = open("/dev/misc/console", O_RDWR)) >= 0) {
            devmgr_launch(svcs_job_handle, "sh:console",
                          countof(argv_sh), argv_sh, envp, fd, NULL, NULL, 0, NULL);
            break;
        }
        zx_nanosleep(zx_deadline_after(ZX_MSEC(100)));
    }
    return 0;
}

static void start_console_shell(void) {
    thrd_t t;
    if ((thrd_create_with_name(&t, console_starter, NULL, "console-starter")) == thrd_success) {
        thrd_detach(t);
    }
}
#else
static void start_console_shell(void) {}
#endif

// Look for VMOs passed as startup handles of PA_HND_TYPE type, and add them to
// the filesystem under the path /boot/VMO_SUBDIR_LEN/<vmo-name>.
static void fetch_vmos(uint_fast8_t type, const char* debug_type_name) {
    for (uint_fast16_t i = 0; true; ++i) {
        zx_handle_t vmo = zx_get_startup_handle(PA_HND(type, i));
        if (vmo == ZX_HANDLE_INVALID)
            break;

        if (type == PA_VMO_VDSO && i == 0) {
            // The first vDSO is the default vDSO.  Since we've stolen
            // the startup handle, launchpad won't find it on its own.
            // So point launchpad at it.
            launchpad_set_vdso_vmo(vmo);
        }

        // The vDSO VMOs have names like "vdso/default", so those
        // become VMO files at "/boot/kernel/vdso/default".
        char name[VMO_SUBDIR_LEN + ZX_MAX_NAME_LEN] = VMO_SUBDIR;
        size_t size;
        zx_status_t status = zx_object_get_property(vmo, ZX_PROP_NAME,
                name + VMO_SUBDIR_LEN, sizeof(name) - VMO_SUBDIR_LEN);
        if (status != ZX_OK) {
            printf("devmgr: zx_object_get_property on %s %u: %s\n",
                   debug_type_name, i, zx_status_get_string(status));
            continue;
        }
        status = zx_vmo_get_size(vmo, &size);
        if (status != ZX_OK) {
            printf("devmgr: zx_vmo_get_size on %s %u: %s\n",
                   debug_type_name, i, zx_status_get_string(status));
            continue;
        }
        if (size == 0) {
            // empty vmos do not get installed
            zx_handle_close(vmo);
            continue;
        }
        if (!strcmp(name + VMO_SUBDIR_LEN, "crashlog")) {
            // the crashlog has a special home
            strcpy(name, "log/last-panic.txt");
        }
        status = bootfs_add_file(name, vmo, 0, size);
        if (status != ZX_OK) {
            printf("devmgr: failed to add %s %u to filesystem: %s\n",
                   debug_type_name, i, zx_status_get_string(status));
        }
    }
}

static void load_cmdline_from_bootfs(void) {
    int fd = open("/boot/config/devmgr", O_RDONLY);
    if (fd < 0) {
        return;
    }
    off_t sz = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);
    char* cfg;
    if ((sz < 0) || ((cfg = malloc(sz + 1)) == NULL)) {
        close(fd);
        return;
    }
    char* x = cfg;
    while (sz > 0) {
        int r = read(fd, x, sz);
        if (r <= 0) {
            close(fd);
            free(cfg);
            return;
        }
        x += r;
        sz -= r;
    }
    *x = 0;
    close(fd);

    x = cfg;
    while (*x) {
        // skip any leading whitespace
        while (isspace(*x)) {
            x++;
        }

        // find the next line (seek for CR or NL)
        char* next = x;
        for (;;) {
            // eof? we're all done then
            if (*next == 0) {
                return;
            }
            if ((*next == '\r') || (*next == '\n')) {
                *next++ = 0;
                break;
            }
            next++;
        }

        // process line if not a comment and not a zero-length name
        if ((*x != '#') && (*x != '=')) {
            for (char *y = x; *y != 0; y++) {
                // space in name is invalid, give up
                if (isspace(*y)) {
                    break;
                }
                // valid looking env entry? store it
                if (*y == '=') {
                    putenv(x);
                    break;
                }
            }
        }

        x = next;
    }
}

int main(int argc, char** argv) {
    // Close the loader-service channel so the service can go away.
    // We won't use it any more (no dlopen calls in this process).
    zx_handle_t loader_svc = dl_set_loader_service(ZX_HANDLE_INVALID);
    zx_handle_close(loader_svc);

    // Ensure that devmgr doesn't try to connect to the global
    // loader sevice (as this leads to deadlocks in devhost v2)
    loader_service_force_local();

    devmgr_io_init();

    root_resource_handle = zx_get_startup_handle(PA_HND(PA_RESOURCE, 0));
    root_job_handle = zx_job_default();

    printf("devmgr: main()\n");

    devmgr_init(root_job_handle);
    devmgr_vfs_init();

    load_cmdline_from_bootfs();

    char** e = environ;
    while (*e) {
        printf("cmdline: %s\n", *e++);
    }

    zx_object_set_property(root_job_handle, ZX_PROP_NAME, "root", 4);

    fetch_vmos(PA_VMO_VDSO, "PA_VMO_VDSO");
    fetch_vmos(PA_VMO_KERNEL_FILE, "PA_VMO_KERNEL_FILE");


    zx_status_t status = zx_job_create(root_job_handle, 0u, &svcs_job_handle);
    if (status < 0) {
        printf("unable to create service job\n");
    }
    zx_object_set_property(svcs_job_handle, ZX_PROP_NAME, "zircon-services", 16);

    status = zx_job_create(root_job_handle, 0u, &fuchsia_job_handle);
    if (status < 0) {
        printf("unable to create service job\n");
    }
    zx_object_set_property(fuchsia_job_handle, ZX_PROP_NAME, "fuchsia", 7);

    // Features like Intel Processor Trace need a dump of ld.so activity.
    // The output has a specific format, and will eventually be recorded
    // via a specific mechanism (zircon tracing support), so we use a specific
    // env var (and don't, for example, piggyback on LD_DEBUG).
    // We enable this pretty early so that we get a trace of as many processes
    // as possible.
    if (getenv(LDSO_TRACE_CMDLINE)) {
        // This takes care of places that clone our environment.
        putenv(strdup(LDSO_TRACE_ENV));
        // There is still devmgr_launch() which does not clone our enviroment.
        // It has its own check.
    }

    // Start crashlogger.
    if (!getenv_bool("crashlogger.disable", false)) {
        static const char* argv_crashlogger[] = {
            "/boot/bin/crashlogger",
            NULL,  // room for -pton
        };
        const char* crashlogger_pt = getenv("crashlogger.pt");
        int argc_crashlogger = 1;
        if (crashlogger_pt && strcmp(crashlogger_pt, "true") == 0) {
            // /dev/misc/intel-pt may not be available yet, so we can't
            // actually turn on PT here. Just tell crashlogger to dump the
            // trace buffers if they're available.
            argv_crashlogger[argc_crashlogger++] = "-pton";
        }

        // Bind the exception port now, to avoid missing any crashes that
        // might occur early on before the crashlogger process has finished
        // initializing.
        zx_handle_t exception_port;
        // This should match the value used by crashlogger.
        const uint64_t kSysExceptionKey = 1166444u;
        if (zx_port_create(0, &exception_port) == ZX_OK &&
            zx_task_bind_exception_port(ZX_HANDLE_INVALID, exception_port,
                                        kSysExceptionKey, 0) == ZX_OK) {
            zx_handle_t handles[] = { exception_port };
            uint32_t handle_types[] = { PA_HND(PA_USER0, 0) };

            devmgr_launch(svcs_job_handle, "crashlogger",
                          argc_crashlogger, argv_crashlogger,
                          NULL, -1, handles, handle_types,
                          countof(handles), NULL);
        }
    }

    zx_channel_create(0, &svc_root_handle, &svc_request_handle);

    start_console_shell();

    if (secondary_bootfs_ready()) {
        devmgr_start_appmgr(NULL);
    }

    thrd_t t;
    if ((thrd_create_with_name(&t, service_starter, NULL, "service-starter")) == thrd_success) {
        thrd_detach(t);
    }

    if ((thrd_create_with_name(&t, service_timeout, NULL, "service-timout")) == thrd_success) {
        thrd_detach(t);
    }

    devmgr_handle_messages();
    printf("devmgr: message handler returned?!\n");
    return 0;
}
