#include <stdio.h>
#include <stdlib.h>
#include <gccore.h>
#include <wiiuse/wpad.h>
#include "loaddol.h"
#include "processor.h"
#include "dol.h"
#include "elf.h"
#include "../fat.h"
#include "../smb.h"
#include "../tools.h"
#include "../wadmanager.h"

extern void __exception_closeall();

int loadelfdol(char *path) {
    //printf("loadelfdol\n");
    void* myBuffer;
    void (*ep)();
    path = trim(path);
    
    FILE* inputFile;
    inputFile = fopen(path, "rb");
    //inputFile = fopen("/apps/geexbox/boot.elf", "rb");

    if (inputFile == NULL) {
        printf(
            "Dol/Elf file does not exist in the path specified in the config file: ");
        printf(path);
        printf("Press A to reboot Wii...\n");
        while (1) {
            WPAD_ScanPads();
            u32 pressed = WPAD_ButtonsDown(0);
            if (pressed & WPAD_BUTTON_A) {
                SYS_ResetSystem(SYS_RESTART, 0, 0);
                //exit(0);
            }
        }
        
    }

    int pos = ftell(inputFile);
    fseek(inputFile, 0, SEEK_END);
    int size = ftell(inputFile);
    fseek(inputFile, pos, SEEK_SET); //return to previous position

    myBuffer = malloc(size);
    fread(myBuffer, 1, size, inputFile);
    
    //Check if valid elf file:
    s32 res;
    res = valid_elf_image(myBuffer);
    //printf("checked elf valid\n");
    if (res == 1) {
        //Elf ok! -> Load entry point of elf file:
        ep = (void(*)()) load_elf_image(myBuffer);
    } else {
        ep = (void(*)()) load_dol_image(myBuffer);
    }

    printf("Entry point: 0x%X\n", (unsigned int) ep);

    fclose(inputFile);
    
    CloseSMB();
    Fat_Unmount(fdev);
    
    // code from geckoloader
    u32 level;
    __IOS_ShutdownSubsystems();
    printf("IOS_ShutdownSubsystems() done\n");
    _CPU_ISR_Disable (level);
    //printf("_CPU_ISR_Disable() done\n");
    __exception_closeall();
    printf("__exception_closeall() done. Jumping to ep now...\n");
    ep();
    _CPU_ISR_Restore (level);
    return 0;
}
