#include <ctype.h>
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "fat.h"
#include "IOSCheck.h"
#include "name.h"
#include "Settings.h"
#include "tools.h"

#define WM_CONFIG_FILE_PATH "sd:/apps/wiimod/wiimod.txt"
#define MAX_FAT_DEVICE_LENGTH   10
#define WAD_ROOT_DIRECTORY  "/wad"

char dbfile[] = "sd:/apps/wiimod/database.txt";
char dbfile2[] = "sd:/database.txt";
char dbfile3[] = "/database.txt";

SETTINGS theSettings;

int GetIntParam(char *);
int GetStartupPath(char *, char *);
int GetStringParam(char *, char *, int);
int ReadConfigFile(char *configFilePath);

s32 initSettings() {
    theSettings.SUIdentified = -1;
    theSettings.checkios = 0;
    theSettings.outputios = 1;
    theSettings.AutoLoadIOS = 0;
    theSettings.printiosdetails = 1;
    theSettings.loadoldcsv = 1;
    theSettings.filterwads = 1;
    theSettings.DeleteDefault = 0;

    // Default startup folder
    strcpy(theSettings.startupPath, WAD_ROOT_DIRECTORY);

    theSettings.fatDeviceIndex = -1; // Means that user has to select

    memset(theSettings.SMB_USER, 0, 20 * sizeof(char));
    memset(theSettings.SMB_PWD, 0, 40 * sizeof(char));
    memset(theSettings.SMB_SHARE, 0, 40 * sizeof(char));
    memset(theSettings.SMB_IP, 0, 20 * sizeof(char));

    ReadConfigFile(WM_CONFIG_FILE_PATH);

    s32 ret = Fat_Mount(&fdevList[0]);
    ret = loadDatabase(dbfile);
    if (ret < 0) {
        ret = loadDatabase(dbfile2);
        if (ret < 0) {
            ret = loadDatabase(dbfile3);
        }
    }
    Fat_Unmount(&fdevList[0]);

    return 0;
}

int ReadConfigFile(char *configFilePath) {
    int retval = 0;
    FILE *fptr;
    char *tmpStr = malloc(MAX_FILE_PATH_LEN);
    char tmpOutStr[40];
    int i;

    if (tmpStr == NULL) return (-1);

    s32 ret = SDCard_Init();

    if (ret < 0) {
        printf(" ERROR! (ret = %d)\n", ret);
        retval = -1;
    } else {
        // Read the file
        fptr = fopen(configFilePath, "rb");
        if (fptr != NULL) {
            // Read the options
            char done = 0;

            while (!done) {
                if (fgets(tmpStr, MAX_FILE_PATH_LEN, fptr) == NULL) {
                    done = 1;
                } else if (isalpha((int) tmpStr[0])) {
                    // Get the password
                    char str[40];
                    if (strncmp(tmpStr, "StartupPath", 11) == 0) {// Get startup path
                        // Get startup Path
                        GetStartupPath(theSettings.startupPath, tmpStr);
                    } else if (strncmp(tmpStr, "FatDevice", 9) == 0) { // FatDevice
                        // Get fatDevice
                        GetStringParam(tmpOutStr, tmpStr, MAX_FAT_DEVICE_LENGTH);
                        for (i = 0; i < 5; i++) {
                            if (strncmp(fdevList[i].mount, tmpOutStr, 2) == 0) {
                                theSettings.fatDeviceIndex = i;
                            }
                        }
                    } else if (strncmp(tmpStr, "checkios", 8) == 0) {
                        // Get checkios
                        theSettings.checkios = (u8) GetIntParam(tmpStr);
                    } else if (strncmp(tmpStr, "outputios", 9) == 0) {
                        // Get outputios
                        theSettings.outputios = (u8) GetIntParam(tmpStr);
                    } else if (strncmp(tmpStr, "printiosdetails", 15) == 0) {
                        // Get printiosdetails
                        theSettings.printiosdetails = (u8) GetIntParam(tmpStr);
                    } else if (strncmp(tmpStr, "AutoLoadIOS", 11) == 0) {
                        // Get AutoLoadIOS
                        theSettings.AutoLoadIOS = (u8) GetIntParam(tmpStr);
                    } else if (strncmp(tmpStr, "loadoldcsv", 10) == 0) {
                        // Get loadoldcsv
                        theSettings.loadoldcsv = (u8) GetIntParam(tmpStr);
                    } else if (strncmp(tmpStr, "DeleteDefaultInsteadRemove", 26) == 0) {
                        // Get DeleteDefaultInsteadRemove
                        theSettings.DeleteDefault = (u8) GetIntParam(tmpStr);
                    } else if (strncmp(tmpStr, "SMB_USER", 8) == 0) {
                        // Get SMB_USER
                        snprintf(str, sizeof(str), "%s", tmpStr + 9);
                        snprintf(theSettings.SMB_USER,
                            sizeof(theSettings.SMB_USER), "%s", trim(str));
                    } else if (strncmp(tmpStr, "SMB_PWD", 7) == 0) {
                        // Get SMB_PWD
                        snprintf(str, sizeof(str), "%s", tmpStr + 8);
                        snprintf(theSettings.SMB_PWD,
                            sizeof(theSettings.SMB_PWD), "%s", trim(str));
                    } else if (strncmp(tmpStr, "SMB_SHARE", 9) == 0) {
                        // Get SMB_SHARE
                        snprintf(str, sizeof(str), "%s", tmpStr + 10);
                        snprintf(theSettings.SMB_SHARE,
                            sizeof(theSettings.SMB_SHARE), "%s", trim(str));
                    } else if (strncmp(tmpStr, "SMB_IP", 6) == 0) {
                        snprintf(str, sizeof(str), "%s", tmpStr + 7);
                        snprintf(theSettings.SMB_IP,
                            sizeof(theSettings.SMB_IP), "%s", trim(str));
                    } else if (strncmp(tmpStr, "filterwads", 10) == 0) {
                        // Get filterwads
                        theSettings.filterwads = (u8) GetIntParam(tmpStr);
                    }
                }
            } // EndWhile

            // Close the config file
            fclose(fptr);
        }
        SDCard_deInit();
    }

    // Free memory
    free(tmpStr);

    return (retval);
} // ReadConfig

int GetIntParam(char *inputStr) {
    int retval = 0;
    int i = 0;
    int len = strlen(inputStr);
    char outParam[40];

    // Find the "="
    while ((inputStr[i] != '=') && (i < len)) {
        i++;
    }
    i++;

    // Get to the first alpha numeric character
    while ((isdigit((int) inputStr[i]) == 0) && (i < len)) {
        i++;
    }

    // Get the string param
    int outCount = 0;
    while ((isdigit((int) inputStr[i])) && (i < len) && (outCount < 40)) {
        outParam[outCount++] = inputStr[i++];
    }
    outParam[outCount] = 0; // NULL terminate
    retval = atoi(outParam);

    return (retval);
} // GetIntParam


int GetStartupPath(char *startupPath, char *inputStr) {
    int i = 0;
    int len = strlen(inputStr);

    // Find the "="
    while ((inputStr[i] != '=') && (i < len)) {
        i++;
    }
    i++;

    // Get to the "/"
    while ((inputStr[i] != '/') && (i < len)) {
        i++;
    }

    // Get the startup Path
    int count = 0;
    while (isascii((int) inputStr[i]) && (i < len) && (inputStr[i] != '\n')
            && (inputStr[i] != '\r') && (inputStr[i] != ' ')) {
        startupPath[count++] = inputStr[i++];
    }
    startupPath[count] = 0; // NULL terminate

    return (0);
} // GetStartupPath

int GetStringParam(char *outParam, char *inputStr, int maxChars) {
    int i = 0;
    int len = strlen(inputStr);

    // Find the "="
    while ((inputStr[i] != '=') && (i < len)) {
        i++;
    }
    i++;

    // Get to the first alpha character
    while ((isalpha((int) inputStr[i]) == 0) && (i < len)) {
        i++;
    }

    // Get the string param
    int outCount = 0;
    while ((isalnum((int) inputStr[i])) && (i < len) && (outCount < maxChars)) {
        outParam[outCount++] = inputStr[i++];
    }
    outParam[outCount] = 0; // NULL terminate

    return (0);
} // GetStringParam
