// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#include "common/log.h"
#include "core/hle/hle.h"
#include "core/hle/service/cfg/cfg.h"
#include "core/hle/service/cfg/cfg_i.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
// Namespace CFG_I

namespace CFG_I {
    
/**
 * CFG_I::GetConfigInfoBlk8 service function
 * This function is called by two command headers,
 * there appears to be no difference between them according to 3dbrew
 *  Inputs:
 *      0 : 0x04010082 / 0x08010082
 *      1 : Size
 *      2 : Block ID
 *      3 : Descriptor for the output buffer
 *      4 : Output buffer pointer
 *  Outputs:
 *      1 : Result of function, 0 on success, otherwise error code
 */
static void GetConfigInfoBlk8(Service::Interface* self) {
    u32* cmd_buffer = Kernel::GetCommandBuffer();
    u32 size = cmd_buffer[1];
    u32 block_id = cmd_buffer[2];
    u8* data_pointer = Memory::GetPointer(cmd_buffer[4]);

    if (data_pointer == nullptr) {
        cmd_buffer[1] = -1; // TODO(Subv): Find the right error code
        return;
    }

    cmd_buffer[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x8, data_pointer).raw;
}

/**
 * CFG_I::UpdateConfigNANDSavegame service function
 * This function is called by two command headers, 
 * there appears to be no difference between them according to 3dbrew
 *  Inputs:
 *      0 : 0x04030000 / 0x08030000
 *  Outputs:
 *      1 : Result of function, 0 on success, otherwise error code
 */
static void UpdateConfigNANDSavegame(Service::Interface* self) {
    u32* cmd_buffer = Kernel::GetCommandBuffer();
    cmd_buffer[1] = Service::CFG::UpdateConfigNANDSavegame().raw;
}

/**
 * CFG_I::FormatConfig service function
 *  Inputs:
 *      0 : 0x08060000
 *  Outputs:
 *      1 : Result of function, 0 on success, otherwise error code
 */
static void FormatConfig(Service::Interface* self) {
    u32* cmd_buffer = Kernel::GetCommandBuffer();
    cmd_buffer[1] = Service::CFG::FormatConfig().raw;
}

const Interface::FunctionInfo FunctionTable[] = {
    {0x04010082, GetConfigInfoBlk8,     "GetConfigInfoBlk8"},
    {0x04020082, nullptr,               "SetConfigInfoBlk4"},
    {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
    {0x04040042, nullptr,               "GetLocalFriendCodeSeedData"},
    {0x04050000, nullptr,               "GetLocalFriendCodeSeed"},
    {0x04060000, nullptr,               "SecureInfoGetRegion"},
    {0x04070000, nullptr,               "SecureInfoGetByte101"},
    {0x04080042, nullptr,               "SecureInfoGetSerialNo"},
    {0x04090000, nullptr,               "UpdateConfigBlk00040003"},
    {0x08010082, GetConfigInfoBlk8,     "GetConfigInfoBlk8"},
    {0x08020082, nullptr,               "SetConfigInfoBlk4"},
    {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
    {0x080400C2, nullptr,               "CreateConfigInfoBlk"},
    {0x08050000, nullptr,               "DeleteConfigNANDSavefile"},
    {0x08060000, FormatConfig,          "FormatConfig"},
    {0x08070000, nullptr,               "Unknown"},
    {0x08080000, nullptr,               "UpdateConfigBlk1"},
    {0x08090000, nullptr,               "UpdateConfigBlk2"},
    {0x080A0000, nullptr,               "UpdateConfigBlk3"},
    {0x080B0082, nullptr,               "SetGetLocalFriendCodeSeedData"},
    {0x080C0042, nullptr,               "SetLocalFriendCodeSeedSignature"},
    {0x080D0000, nullptr,               "DeleteCreateNANDLocalFriendCodeSeed"},
    {0x080E0000, nullptr,               "VerifySigLocalFriendCodeSeed"},
    {0x080F0042, nullptr,               "GetLocalFriendCodeSeedData"},
    {0x08100000, nullptr,               "GetLocalFriendCodeSeed"},
    {0x08110084, nullptr,               "SetSecureInfo"},
    {0x08120000, nullptr,               "DeleteCreateNANDSecureInfo"},
    {0x08130000, nullptr,               "VerifySigSecureInfo"},
    {0x08140042, nullptr,               "SecureInfoGetData"},
    {0x08150042, nullptr,               "SecureInfoGetSignature"},
    {0x08160000, nullptr,               "SecureInfoGetRegion"},
    {0x08170000, nullptr,               "SecureInfoGetByte101"},
    {0x08180042, nullptr,               "SecureInfoGetSerialNo"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interface class

Interface::Interface() {
    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}

Interface::~Interface() {
}

} // namespace
