#include "Log.h"
#include "arch/CPU.h"
#include "arch/MMU.h"
#include "arch/Serial.h"
#include "arch/Timer.h"
#include "boot/Init.h"
#include "config.h"
#include "memory/Heap.h"
#include "memory/MemoryManager.h"
#include "video/TextConsole.h"
#include <luna/Units.h>

Result<void> init()
{
    kinfoln("Starting Moon %s", MOON_VERSION);

    kinfoln("Current platform: %s", CPU::platform_string());

    kinfoln("Current processor: %s", TRY(CPU::identify()));

    Timer::init();

    CPU::platform_finish_init();

    CPU::enable_interrupts();

    char buffer[64];
    to_dynamic_unit(MemoryManager::total(), buffer, sizeof(buffer));
    kinfoln("Total memory:    %s", buffer);
    to_dynamic_unit(MemoryManager::free(), buffer, sizeof(buffer));
    kinfoln("Free memory:     %s", buffer);
    to_dynamic_unit(MemoryManager::used(), buffer, sizeof(buffer));
    kinfoln("Used memory:     %s", buffer);
    to_dynamic_unit(MemoryManager::reserved(), buffer, sizeof(buffer));
    kinfoln("Reserved memory: %s", buffer);

    return {};
}

extern "C" [[noreturn]] void _start()
{
    Init::check_magic();
    Init::early_init();
    auto rc = init();
    if (rc.has_error()) kerrorln("Runtime error: %s", rc.error_string());
    CPU::efficient_halt();
}