#include <kernel/tty.h>
#include <kernel/task.h>
#include "interrupt.h" 
#include <stddef.h>
#include <debugging.h>
#include <kernel/io/keyboard.h>
#include "../io.h"

uint8_t test = 'a';

static void stack_trace() 
{
    uint32_t* stack = 0;
    asm("mov %%esp, %0" : "=r" (stack));
    for (int i = 0; i < 25; i++) {
        uint32_t* current_address = stack + (i * 4);
        print_hex_bytes(&current_address, 4); 
        terminal_writestring(":   ");
        print_hex_bytes(current_address, 4); 
        terminal_putchar('\n');
    }
}

__attribute__((interrupt)) void divide_by_zero(struct interrupt_frame*) 
{
    terminal_writestring("Yo dude u cant divide by zero yao\n");
    while (1) { }
}

__attribute__((interrupt)) void general_protection_fault(struct interrupt_frame*)
{
    terminal_writestring("GPF handler called\n");
    while (1) {
        asm("cli");
        asm("hlt");
    }
}

__attribute__((interrupt)) void double_fault(struct interrupt_frame*) 
{
    stack_trace();
    terminal_writestring("2 Errors in a row, u better behave naughty naughty\n");
    while (1) { 
        asm("cli");
        asm("hlt");
    }
}

__attribute__((interrupt)) void exception(struct interrupt_frame*)
{
    terminal_writestring("Some weird error code stuff\n");
    while (1) { }
}

__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame*)
{
    terminal_writestring("Keyboard Interrupt\n");
    uint8_t scancode = inb(0x60);
    handle_keyboard(scancode);
    outb(0x20, 0x20);
}

__attribute__((interrupt)) void irq_1(struct interrupt_frame*) 
{
    terminal_writestring("PIC 1\n");
    outb(0x20, 0x20);
}

__attribute__((interrupt)) void irq_2(struct interrupt_frame*) 
{
    terminal_writestring("PIC 2\n");
    outb(0xA0, 0x20);
    outb(0x20, 0x20);
}