// Copyright 2017 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 <fcntl.h>
#include <fuchsia/device/manager/c/fidl.h>
#include <fuchsia/hardware/pty/c/fidl.h>
#include <hid/usages.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/unsafe.h>
#include <lib/zx/channel.h>
#include <string.h>
#include <sys/param.h>

#include "keyboard-vt100.h"
#include "keyboard.h"
#include "vc.h"

static struct list_node g_vc_list = LIST_INITIAL_VALUE(g_vc_list);
static unsigned g_vc_count = 0;
static unsigned g_active_vc_index;

vc_t* g_active_vc;
int g_status_width = 0;

// Process key sequences that affect the console (scrolling, switching
// console, etc.) without sending input to the current console.  This
// returns whether this key press was handled.
static bool vc_handle_control_keys(uint8_t keycode, int modifiers) {
    switch (keycode) {
    case HID_USAGE_KEY_F1 ... HID_USAGE_KEY_F10:
        if (modifiers & MOD_ALT) {
            vc_set_active(keycode - HID_USAGE_KEY_F1, NULL);
            return true;
        }
        break;

    case HID_USAGE_KEY_TAB:
        if (modifiers & MOD_ALT) {
            if (modifiers & MOD_SHIFT) {
                vc_set_active(g_active_vc_index == 0 ? g_vc_count - 1 : g_active_vc_index - 1, NULL);
            } else {
                vc_set_active(g_active_vc_index == g_vc_count - 1 ? 0 : g_active_vc_index + 1, NULL);
            }
            return true;
        }
        break;

    case HID_USAGE_KEY_VOL_UP:
        vc_set_active(g_active_vc_index == 0 ? g_vc_count - 1 : g_active_vc_index - 1, NULL);
        break;

    case HID_USAGE_KEY_VOL_DOWN:
        vc_set_active(g_active_vc_index == g_vc_count - 1 ? 0 : g_active_vc_index + 1, NULL);
        break;

    case HID_USAGE_KEY_UP:
        if (modifiers & MOD_ALT) {
            vc_scroll_viewport(g_active_vc, -1);
            return true;
        }
        break;
    case HID_USAGE_KEY_DOWN:
        if (modifiers & MOD_ALT) {
            vc_scroll_viewport(g_active_vc, 1);
            return true;
        }
        break;
    case HID_USAGE_KEY_PAGEUP:
        if (modifiers & MOD_SHIFT) {
            vc_scroll_viewport(g_active_vc, -(vc_rows(g_active_vc) / 2));
            return true;
        }
        break;
    case HID_USAGE_KEY_PAGEDOWN:
        if (modifiers & MOD_SHIFT) {
            vc_scroll_viewport(g_active_vc, vc_rows(g_active_vc) / 2);
            return true;
        }
        break;
    case HID_USAGE_KEY_HOME:
        if (modifiers & MOD_SHIFT) {
            vc_scroll_viewport_top(g_active_vc);
            return true;
        }
        break;
    case HID_USAGE_KEY_END:
        if (modifiers & MOD_SHIFT) {
            vc_scroll_viewport_bottom(g_active_vc);
            return true;
        }
        break;
    }
    return false;
}

static bool connect_to_service(const char* service, zx::channel* channel) {
    zx::channel channel_remote;
    zx_status_t status = zx::channel::create(0, channel, &channel_remote);
    if (status != ZX_OK) {
        fprintf(stderr, "failed to create channel: %d\n", status);
        return false;
    }

    status = fdio_service_connect(service, channel_remote.release());
    if (status != ZX_OK) {
        fprintf(stderr, "failed to connect to service: %d\n", status);
        return false;
    }

    return true;
}

// Process key sequences that affect the low-level control of the system
// (switching display ownership, rebooting).  This returns whether this key press
// was handled.
static bool vc_handle_device_control_keys(uint8_t keycode, int modifiers) {
    switch (keycode) {
    case HID_USAGE_KEY_DELETE:
        // Provide a CTRL-ALT-DEL reboot sequence
        if ((modifiers & MOD_CTRL) && (modifiers & MOD_ALT)) {
            zx::channel channel;
            if (connect_to_service("/svc/fuchsia.device.manager.Administrator", &channel)) {
                zx_status_t call_status;
                const auto flag = fuchsia_device_manager_SUSPEND_FLAG_REBOOT;
                auto status = fuchsia_device_manager_AdministratorSuspend(channel.get(), flag,
                                                                          &call_status);
                if (status != ZX_OK || call_status != ZX_OK) {
                    fprintf(stderr, "Failed to reboot, statuses: local: %d remote: %d\n",
                            status, call_status);
                }
            }
            return true;
        }
        break;

    case HID_USAGE_KEY_ESC:
        if (modifiers & MOD_ALT) {
            vc_toggle_framebuffer();
            return true;
        }
        break;
    }

    return false;
}

zx_status_t vc_set_active(int num, vc_t* to_vc) {
    vc_t* vc = NULL;
    int i = 0;
    list_for_every_entry (&g_vc_list, vc, vc_t, node) {
        if ((num == i) || (to_vc == vc)) {
            if (vc == g_active_vc) {
                return ZX_OK;
            }
            if (g_active_vc) {
                g_active_vc->active = false;
                g_active_vc->flags &= ~VC_FLAG_HASOUTPUT;
            }
            vc->active = true;
            vc->flags &= ~VC_FLAG_HASOUTPUT;
            g_active_vc = vc;
            g_active_vc_index = i;
            vc_full_repaint(vc);
            vc_render(vc);
            return ZX_OK;
        }
        i++;
    }
    return ZX_ERR_NOT_FOUND;
}

void vc_show_active() {
    vc_t* vc = NULL;
    list_for_every_entry (&g_vc_list, vc, vc_t, node) {
        vc_attach_gfx(vc);
        if ((vc->fd >= 0) && isatty(vc->fd)) {
            fuchsia_hardware_pty_WindowSize wsz = {
                .width = vc->columns,
                .height = vc->rows,
            };

            fdio_t* io = fdio_unsafe_fd_to_io(vc->fd);
            zx_status_t status;
            fuchsia_hardware_pty_DeviceSetWindowSize(fdio_unsafe_borrow_channel(io), &wsz, &status);
            fdio_unsafe_release(io);
        }
        if (vc == g_active_vc) {
            vc_full_repaint(vc);
            vc_render(vc);
        }
    }
}

void vc_status_update() {
    vc_t* vc = NULL;
    unsigned i = 0;
    int x = 0;

    int w = g_status_width / (g_vc_count + 1);
    if (w < MIN_TAB_WIDTH) {
        w = MIN_TAB_WIDTH;
    } else if (w > MAX_TAB_WIDTH) {
        w = MAX_TAB_WIDTH;
    }

    char tmp[w];

    vc_status_clear();
    list_for_every_entry (&g_vc_list, vc, vc_t, node) {
        unsigned fg;
        if (vc->active) {
            fg = STATUS_COLOR_ACTIVE;
        } else if (vc->flags & VC_FLAG_HASOUTPUT) {
            fg = STATUS_COLOR_UPDATED;
        } else {
            fg = STATUS_COLOR_DEFAULT;
        }

        int lines = vc_get_scrollback_lines(vc);
        char L = (lines > 0) && (-vc->viewport_y < lines) ? '<' : '[';
        char R = (vc->viewport_y < 0) ? '>' : ']';

        snprintf(tmp, w, "%c%u%c %s", L, i, R, vc->title);
        vc_status_write(x, fg, tmp);
        x += w;
        i++;
    }
    vc_status_commit();
}

void handle_key_press(uint8_t keycode, int modifiers) {
    // Handle vc-level control keys
    if (vc_handle_device_control_keys(keycode, modifiers))
        return;

    // Handle other keys only if we own the display
    if (!g_vc_owns_display)
        return;

    // Handle other control keys
    if (vc_handle_control_keys(keycode, modifiers))
        return;

    vc_t* vc = g_active_vc;
    char output[4];
    uint32_t length = hid_key_to_vt100_code(
        keycode, modifiers, vc->keymap, output, sizeof(output));
    if (length > 0) {
        if (vc->fd >= 0) {
            write(vc->fd, output, length);
        }
        vc_scroll_viewport_bottom(vc);
    }
}

ssize_t vc_write(vc_t* vc, const void* buf, size_t count, zx_off_t off) {
    vc->invy0 = vc_rows(vc) + 1;
    vc->invy1 = -1;
    const uint8_t* str = (const uint8_t*)buf;
    for (size_t i = 0; i < count; i++) {
        vc->textcon.putc(&vc->textcon, str[i]);
    }
    vc_flush(vc);
    if (!(vc->flags & VC_FLAG_HASOUTPUT) && !vc->active) {
        vc->flags |= VC_FLAG_HASOUTPUT;
        vc_status_update();
    }
    return count;
}

// Create a new vc_t and add it to the console list.
zx_status_t vc_create(vc_t** vc_out, bool special) {
    zx_status_t status;
    vc_t* vc;
    if ((status = vc_alloc(&vc, special)) < 0) {
        return status;
    }

    // add to the vc list
    list_add_tail(&g_vc_list, &vc->node);
    g_vc_count++;

    // make this the active vc if it's the first one
    if (!g_active_vc) {
        vc_set_active(-1, vc);
    } else {
        vc_render(g_active_vc);
    }

    *vc_out = vc;
    return ZX_OK;
}

void vc_destroy(vc_t* vc) {
    list_delete(&vc->node);
    g_vc_count -= 1;

    if (vc->active) {
        g_active_vc = NULL;
        if (g_active_vc_index >= g_vc_count) {
            g_active_vc_index = g_vc_count - 1;
        }
        vc_set_active(g_active_vc_index, NULL);
    } else if (g_active_vc) {
        vc_full_repaint(g_active_vc);
        vc_render(g_active_vc);
    }

    vc_free(vc);
}
