// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2009 Corey Tabaka
// Copyright (c) 2016 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

#include <platform/keyboard.h>

#include "platform_p.h"
#include <arch/x86.h>
#include <arch/x86/apic.h>
#include <assert.h>
#include <ctype.h>
#include <debug.h>
#include <dev/interrupt.h>
#include <err.h>
#include <kernel/thread.h>
#include <lib/cbuf.h>
#include <platform.h>
#include <platform/console.h>
#include <platform/pc.h>
#include <platform/timer.h>
#include <reg.h>
#include <sys/types.h>
#include <trace.h>

#define LOCAL_TRACE 0

static inline uint8_t i8042_read_data(void) {
    return inp(I8042_DATA_REG);
}

static inline uint8_t i8042_read_status(void) {
    return inp(I8042_STATUS_REG);
}

static inline void i8042_write_data(uint8_t val) {
    outp(I8042_DATA_REG, val);
}

static inline void i8042_write_command(uint8_t val) {
    outp(I8042_COMMAND_REG, val);
}

/*
 * timeout in milliseconds
 */
#define I8042_CTL_TIMEOUT 500

/*
 * status register bits
 */
#define I8042_STR_PARITY 0x80
#define I8042_STR_TIMEOUT 0x40
#define I8042_STR_AUXDATA 0x20
#define I8042_STR_KEYLOCK 0x10
#define I8042_STR_CMDDAT 0x08
#define I8042_STR_MUXERR 0x04
#define I8042_STR_IBF 0x02
#define I8042_STR_OBF 0x01

/*
 * control register bits
 */
#define I8042_CTR_KBDINT 0x01
#define I8042_CTR_AUXINT 0x02
#define I8042_CTR_IGNKEYLK 0x08
#define I8042_CTR_KBDDIS 0x10
#define I8042_CTR_AUXDIS 0x20
#define I8042_CTR_XLATE 0x40

/*
 * commands
 */
#define I8042_CMD_CTL_RCTR 0x0120
#define I8042_CMD_CTL_WCTR 0x1060
#define I8042_CMD_CTL_TEST 0x01aa

#define I8042_CMD_KBD_DIS 0x00ad
#define I8042_CMD_KBD_EN 0x00ae
#define I8042_CMD_PULSE_RESET 0x00fe
#define I8042_CMD_KBD_TEST 0x01ab
#define I8042_CMD_KBD_MODE 0x01f0

/*
 * used for flushing buffers. the i8042 internal buffer shoudn't exceed this.
 */
#define I8042_BUFFER_LENGTH 32

/* extended keys that aren't pure ascii */
enum extended_keys {
    KEY_RETURN = 0x80,
    KEY_ESC,
    KEY_LSHIFT,
    KEY_RSHIFT,
    KEY_LCTRL,
    KEY_RCTRL,
    KEY_LALT,
    KEY_RALT,
    KEY_CAPSLOCK,
    KEY_LWIN,
    KEY_RWIN,
    KEY_MENU,
    KEY_F1,
    KEY_F2,
    KEY_F3,
    KEY_F4,
    KEY_F5,
    KEY_F6,
    KEY_F7,
    KEY_F8,
    KEY_F9,
    KEY_F10,
    KEY_F11,
    KEY_F12,
    KEY_F13,
    KEY_F14,
    KEY_F15,
    KEY_F16,
    KEY_F17,
    KEY_F18,
    KEY_F19,
    KEY_F20,
    KEY_PRTSCRN,
    KEY_SCRLOCK,
    KEY_PAUSE,
    KEY_TAB,
    KEY_BACKSPACE,
    KEY_INS,
    KEY_DEL,
    KEY_HOME,
    KEY_END,
    KEY_PGUP,
    KEY_PGDN,
    KEY_ARROW_UP,
    KEY_ARROW_DOWN,
    KEY_ARROW_LEFT,
    KEY_ARROW_RIGHT,
    KEY_PAD_NUMLOCK,
    KEY_PAD_DIVIDE,
    KEY_PAD_MULTIPLY,
    KEY_PAD_MINUS,
    KEY_PAD_PLUS,
    KEY_PAD_ENTER,
    KEY_PAD_PERIOD,
    KEY_PAD_0,
    KEY_PAD_1,
    KEY_PAD_2,
    KEY_PAD_3,
    KEY_PAD_4,
    KEY_PAD_5,
    KEY_PAD_6,
    KEY_PAD_7,
    KEY_PAD_8,
    KEY_PAD_9,

    _KEY_LAST,
};

static_assert(_KEY_LAST < 0x100, "");

/* scancode translation tables */
const uint8_t pc_keymap_set1_lower[128] = {
    /* 0x00 */ 0, KEY_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', KEY_BACKSPACE, KEY_TAB,
    /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', KEY_RETURN, KEY_LCTRL, 'a', 's',
    /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', KEY_LSHIFT, '\\', 'z', 'x', 'c', 'v',
    /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT, '*', KEY_LALT, ' ', KEY_CAPSLOCK, KEY_F1, KEY_F2,
    KEY_F3, KEY_F4, KEY_F5,
    /* 0x40 */ KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_PAD_NUMLOCK, KEY_SCRLOCK, KEY_PAD_7, KEY_PAD_8,
    KEY_PAD_9, KEY_PAD_MINUS, KEY_PAD_4, KEY_PAD_5, KEY_PAD_6, KEY_PAD_PLUS, KEY_PAD_1,
    /* 0x50 */ KEY_PAD_2, KEY_PAD_3, KEY_PAD_0, KEY_PAD_PERIOD, 0, 0, 0, KEY_F11, KEY_F12, 0, 0, 0, 0, 0, 0, 0,
};

const uint8_t pc_keymap_set1_upper[128] = {
    /* 0x00 */ 0, KEY_ESC, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', KEY_BACKSPACE, KEY_TAB,
    /* 0x10 */ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', KEY_RETURN, KEY_LCTRL, 'A', 'S',
    /* 0x20 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', KEY_LSHIFT, '|', 'Z', 'X', 'C', 'V',
    /* 0x30 */ 'B', 'N', 'M', '<', '>', '?', KEY_RSHIFT, '*', KEY_LALT, ' ', KEY_CAPSLOCK, KEY_F1, KEY_F2,
    KEY_F3, KEY_F4, KEY_F5,
    /* 0x40 */ KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_PAD_NUMLOCK, KEY_SCRLOCK, KEY_PAD_7, KEY_PAD_8,
    KEY_PAD_9, KEY_PAD_MINUS, KEY_PAD_4, KEY_PAD_5, KEY_PAD_6, KEY_PAD_PLUS, KEY_PAD_1,
    /* 0x50 */ KEY_PAD_2, KEY_PAD_3, KEY_PAD_0, KEY_PAD_PERIOD, 0, 0, 0, KEY_F11, KEY_F12, 0, 0, 0, 0, 0, 0, 0,
};

const uint8_t pc_keymap_set1_e0[128] = {
    /* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_PAD_ENTER, KEY_RCTRL, 0, 0,
    /* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    /* 0x30 */ 0, 0, 0, 0, 0, KEY_PAD_DIVIDE, 0, KEY_PRTSCRN, KEY_RALT, 0, 0, 0, 0, 0, 0, 0,
    /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, KEY_HOME, KEY_ARROW_UP, KEY_PGUP, 0, KEY_ARROW_LEFT, 0, KEY_ARROW_RIGHT, 0, KEY_END,
    /* 0x50 */ KEY_ARROW_DOWN, KEY_PGDN, KEY_INS, 0, 0, 0, 0, 0, 0, 0, 0, KEY_LWIN, KEY_RWIN, KEY_MENU, 0, 0};

/*
 * state key flags
 */
static bool key_lshift;
static bool key_rshift;
static int last_code;

static cbuf_t* key_buf;

static void i8042_process_scode(uint8_t scode, unsigned int flags) {
    // is this a multi code sequence?
    bool multi = (last_code == 0xe0);

    // update the last received code
    last_code = scode;

    // save the key up event bit
    bool key_up = !!(scode & 0x80);
    scode &= 0x7f;

    // translate the key based on our translation table
    uint8_t key_code;
    if (multi) {
        key_code = pc_keymap_set1_e0[scode];
    } else if (key_lshift || key_rshift) {
        key_code = pc_keymap_set1_upper[scode];
    } else {
        key_code = pc_keymap_set1_lower[scode];
    }

    LTRACEF("scancode 0x%x, keyup %d, multi %d: keycode 0x%x\n", scode, !!key_up, multi, key_code);

    // generate a character string to feed into the queue
    char str[4] = {0};
    switch (key_code) {
    // for all the usual ascii strings, generate the target string directly
    case 1 ... 0x7f:
        str[0] = key_code;
        break;

    // a few special keys we can generate stuff for directly
    case KEY_RETURN:
    case KEY_PAD_ENTER:
        str[0] = '\n';
        break;
    case KEY_BACKSPACE:
        str[0] = '\b';
        break;
    case KEY_TAB:
        str[0] = '\t';
        break;

    // generate vt100 key codes for arrows
    case KEY_ARROW_UP:
        str[0] = 0x1b;
        str[1] = '[';
        str[2] = 65;
        break;
    case KEY_ARROW_DOWN:
        str[0] = 0x1b;
        str[1] = '[';
        str[2] = 66;
        break;
    case KEY_ARROW_RIGHT:
        str[0] = 0x1b;
        str[1] = '[';
        str[2] = 67;
        break;
    case KEY_ARROW_LEFT:
        str[0] = 0x1b;
        str[1] = '[';
        str[2] = 68;
        break;

    // left and right shift are special
    case KEY_LSHIFT:
        key_lshift = !key_up;
        break;
    case KEY_RSHIFT:
        key_rshift = !key_up;
        break;

    // everything else we just eat
    default:; // nothing
    }

    if (!key_up) {
        for (uint i = 0; str[i] != '\0'; i++) {
            LTRACEF("char 0x%hhx (%c)\n", str[i], isprint(str[i]) ? (str[i]) : ' ');
            cbuf_write_char(key_buf, str[i]);
        }
    }
}

static int i8042_wait_read(void) {
    int i = 0;
    while ((~i8042_read_status() & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) {
        spin(10);
        i++;
    }
    return -(i == I8042_CTL_TIMEOUT);
}

static int i8042_wait_write(void) {
    int i = 0;
    while ((i8042_read_status() & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) {
        spin(10);
        i++;
    }
    return -(i == I8042_CTL_TIMEOUT);
}

static int i8042_flush(void) {
    unsigned char data __UNUSED;
    int i = 0;

    while ((i8042_read_status() & I8042_STR_OBF) && (i++ < I8042_BUFFER_LENGTH)) {
        spin(10);
        data = i8042_read_data();
    }

    return i;
}

static int i8042_command(uint8_t* param, uint16_t command) {
    int retval = 0, i = 0;

    retval = i8042_wait_write();
    if (!retval) {
        i8042_write_command(static_cast<uint8_t>(command));
    }

    if (!retval) {
        for (i = 0; i < ((command >> 12) & 0xf); i++) {
            if ((retval = i8042_wait_write())) {
                break;
            }

            i8042_write_data(param[i]);
        }
    }

    if (!retval) {
        for (i = 0; i < ((command >> 8) & 0xf); i++) {
            if ((retval = i8042_wait_read())) {
                break;
            }

            if (i8042_read_status() & I8042_STR_AUXDATA) {
                param[i] = static_cast<uint8_t>(~i8042_read_data());
            } else {
                param[i] = i8042_read_data();
            }
        }
    }

    return retval;
}

static int keyboard_command(uint8_t* param, int command) {
    int retval = 0, i = 0;

    retval = i8042_wait_write();
    if (!retval) {
        i8042_write_data(static_cast<uint8_t>(command));
    }

    if (!retval) {
        for (i = 0; i < ((command >> 12) & 0xf); i++) {
            if ((retval = i8042_wait_write())) {
                break;
            }

            i8042_write_data(param[i]);
        }
    }

    if (!retval) {
        for (i = 0; i < ((command >> 8) & 0xf); i++) {
            if ((retval = i8042_wait_read())) {
                break;
            }

            if (i8042_read_status() & I8042_STR_AUXDATA) {
                param[i] = static_cast<uint8_t>(~i8042_read_data());
            } else {
                param[i] = i8042_read_data();
            }
        }
    }

    return retval;
}

static interrupt_eoi i8042_interrupt(void* arg) {
    // keep handling status on the keyboard controller until no bits are set we care about
    bool retry;
    do {
        retry = false;

        uint8_t str = i8042_read_status();

        // check for incoming data from the controller
        if (str & I8042_STR_OBF) {
            uint8_t data = i8042_read_data();
            i8042_process_scode(data,
                                ((str & I8042_STR_PARITY) ? I8042_STR_PARITY : 0) |
                                ((str & I8042_STR_TIMEOUT) ? I8042_STR_TIMEOUT : 0));

            retry = true;
        }

        // TODO: check other status bits here
    } while (retry);
    return IRQ_EOI_DEACTIVATE;
}

int platform_read_key(char* c) {
    ssize_t len = cbuf_read_char(key_buf, c, true);
    return static_cast<int>(len);
}

void platform_init_keyboard(cbuf_t* buffer) {
    uint8_t ctr;

    key_buf = buffer;

    i8042_flush();

    if (i8042_command(&ctr, I8042_CMD_CTL_RCTR)) {
        dprintf(SPEW, "Failed to read CTR while initializing i8042\n");
        return;
    }

    // turn on translation
    ctr |= I8042_CTR_XLATE;

    // enable keyboard and keyboard irq
    ctr &= static_cast<uint8_t>(~I8042_CTR_KBDDIS);
    ctr |= I8042_CTR_KBDINT;

    if (i8042_command(&ctr, I8042_CMD_CTL_WCTR)) {
        dprintf(SPEW, "Failed to write CTR while initializing i8042\n");
        return;
    }

    /* enable PS/2 port */
    i8042_command(NULL, I8042_CMD_KBD_EN);

    /* send a enable scan command to the keyboard */
    keyboard_command(&ctr, 0x1f4);

    uint32_t irq = apic_io_isa_to_global(ISA_IRQ_KEYBOARD);
    zx_status_t status = register_int_handler(irq, &i8042_interrupt, NULL);
    DEBUG_ASSERT(status == ZX_OK);
    unmask_interrupt(irq);

    i8042_interrupt(NULL);
}

void pc_keyboard_reboot(void) {
    if (i8042_wait_write() != 0) {
        return;
    }

    i8042_write_command(I8042_CMD_PULSE_RESET);
    // Wait a second for the command to process before declaring failure
    spin(1000000);
}
