#include <windows.h>

#include "ConnAPI.h"
#include "PCCAPIUtils.h"

#include "stringutils.h"

std::string CONAError2String(DWORD error)
{
    switch(error)
    {
// Common error codes:
    case CONA_OK: return "CONA_OK: Succeeded";
    case ECONA_INIT_FAILED: return "ECONA_INIT_FAILED: DLL initialization failed";
    case ECONA_INIT_FAILED_COM_INTERFACE: return "ECONA_INIT_FAILED_COM_INTERFACE: DLL initialization failed";
    case ECONA_NOT_INITIALIZED: return "ECONA_NOT_INITIALIZED: API is not initialized";
    case ECONA_UNSUPPORTED_API_VERSION: return "ECONA_UNSUPPORTED_API_VERSION: API version not supported";
    case ECONA_NOT_SUPPORTED_MANUFACTURER: return "ECONA_NOT_SUPPORTED_MANUFACTURER: Manufacturer is not supported";

    case ECONA_UNKNOWN_ERROR: return "ECONA_UNKNOWN_ERROR: Failed, unknown error";
    case ECONA_UNKNOWN_ERROR_DEVICE: return "ECONA_UNKNOWN_ERROR_DEVICE: Failed, unknown error from Device";
    case ECONA_INVALID_POINTER: return "ECONA_INVALID_POINTER: Required pointer is invalid";
    case ECONA_INVALID_PARAMETER: return "ECONA_INVALID_PARAMETER: Invalid parameter value";
    case ECONA_INVALID_HANDLE: return "ECONA_INVALID_HANDLE: Invalid HANDLE";
    case ECONA_NOT_ENOUGH_MEMORY: return "ECONA_NOT_ENOUGH_MEMORY: Memory allocation failed in PC";
    case ECONA_WRONG_THREAD: return "Failed, Called interface was marshalled for a different thread";

    case ECONA_CANCELLED: return "ECONA_CANCELLED: Operation cancelled by ConnectivityAPI-User";
    case ECONA_NOTHING_TO_CANCEL: return "ECONA_NOTHING_TO_CANCEL: No running functions";
    case ECONA_FAILED_TIMEOUT: return "ECONA_FAILED_TIMEOUT: Operation failed because of timeout";
    case ECONA_NOT_SUPPORTED_DEVICE: return "ECONA_NOT_SUPPORTED_DEVICE: Device does not support operation";
    case ECONA_NOT_SUPPORTED_PC: return "ECONA_NOT_SUPPORTED_PC: Connectivity API does not support operation (not implemented)";

// Device manager and device connection releated error:
    case ECONA_DEVICE_NOT_FOUND: return "ECONA_DEVICE_NOT_FOUND: Given phone is not connected (refresh device list)";
    case ECONA_NO_CONNECTION_VIA_MEDIA: return "ECONA_NO_CONNECTION_VIA_MEDIA: Phone is connected but not via given Media";
    case ECONA_NO_CONNECTION_VIA_DEVID: return "ECONA_NO_CONNECTION_VIA_DEVID: Phone is not connected with given DevID";
    case ECONA_INVALID_CONNECTION_TYPE: return "ECONA_INVALID_CONNECTION_TYPE: Connection type was invalid";
    case ECONA_NOT_SUPPORTED_CONNECTION_TYPE: return "ECONA_NOT_SUPPORTED_CONNECTION_TYPE: Device does not support connection type";
    case ECONA_CONNECTION_BUSY: return "ECONA_CONNECTION_BUSY: Other application is reserved connection";
    case ECONA_CONNECTION_LOST: return "ECONA_CONNECTION_LOST: Connection is lost to Device";
    case ECONA_CONNECTION_REMOVED: return "ECONA_CONNECTION_REMOVED: Connection removed, other application has reserved connection.";
    case ECONA_CONNECTION_FAILED: return "ECONA_CONNECTION_FAILED: Connection failed, unknown reason";
    case ECONA_SUSPEND: return "ECONA_SUSPEND: Connection removed, PC goes suspend state";
    case ECONA_NAME_ALREADY_EXISTS: return "ECONA_NAME_ALREADY_EXISTS: Friendly name already exist";
    case ECONA_MEDIA_IS_NOT_WORKING: return "ECONA_MEDIA_IS_NOT_WORKING: Target media is active but it is not working (e.g. BT-hardware stopped or removed)";
    case ECONA_CACHE_IS_NOT_AVAILABLE: return "ECONA_CACHE_IS_NOT_AVAILABLE: Cache is not available (CONASearchDevices)";
    case ECONA_MEDIA_IS_NOT_ACTIVE: return "ECONA_MEDIA_IS_NOT_ACTIVE: Target media is active (or ready yet)";

// Device pairing releated errors:
    case ECONA_DEVICE_PAIRING_FAILED: return "ECONA_DEVICE_PAIRING_FAILED: Pairing failed.";
    case ECONA_DEVICE_PASSWORD_WRONG: return "ECONA_DEVICE_PASSWORD_WRONG: Wrong password on device.";
    case ECONA_DEVICE_PASSWORD_INVALID: return "ECONA_DEVICE_PASSWORD_INVALID: Password includes invalid characters or missing.";

// File System errors:
    case ECONA_ALL_LISTED: return "ECONA_ALL_LISTED: All items are listed";
    case ECONA_MEMORY_FULL: return "ECONA_MEMORY_FULL: Device memory full";

// File System error for file functions:
    case ECONA_FILE_NAME_INVALID: return "ECONA_FILE_NAME_INVALID: File name includes invalid characters in Device or PC";
    case ECONA_FILE_NAME_TOO_LONG: return "ECONA_FILE_NAME_TOO_LONG: File name includes too many characters in Device or PC";
    case ECONA_FILE_ALREADY_EXIST: return "ECONA_FILE_ALREADY_EXIST: File already exists in Device or PC";
    case ECONA_FILE_NOT_FOUND: return "ECONA_FILE_NOT_FOUND: File does not exist in Device or PC";
    case ECONA_FILE_NO_PERMISSION: return "ECONA_FILE_NO_PERMISSION: Not allowed to perform required operation to file in Device or PC";
    case ECONA_FILE_COPYRIGHT_PROTECTED: return "ECONA_FILE_COPYRIGHT_PROTECTED: Not allowed to perform required operation to file in Device or PC";
    case ECONA_FILE_BUSY: return "ECONA_FILE_BUSY: Other application has reserved file in Device or PC";
    case ECONA_FILE_TOO_BIG_DEVICE: return "ECONA_FILE_TOO_BIG_DEVICE: Device rejected the operation because file size is too big";
    case ECONA_FILE_TYPE_NOT_SUPPORTED: return "ECONA_FILE_TYPE_NOT_SUPPORTED: Device rejected the operation because file is unsupported type";
    case ECONA_FILE_NO_PERMISSION_ON_PC: return "ECONA_FILE_NO_PERMISSION_ON_PC: ECONA_FILE_NO_PERMISSION_ON_PC";

// File System error for folder functions:
    case ECONA_INVALID_DATA_DEVICE: return "ECONA_INVALID_DATA_DEVICE: Device's folder contains invalid data";
    case ECONA_CURRENT_FOLDER_NOT_FOUND: return "ECONA_CURRENT_FOLDER_NOT_FOUND: Current folder is invalid in device (e.g MMC card removed).";
    case ECONA_FOLDER_PATH_TOO_LONG: return "ECONA_FOLDER_PATH_TOO_LONG: Current folder max unicode charaters count is limited to 255.";
    case ECONA_FOLDER_NAME_INVALID: return "ECONA_FOLDER_NAME_INVALID: Folder name includes invalid characters in Device or PC";
    case ECONA_FOLDER_ALREADY_EXIST: return "ECONA_FOLDER_ALREADY_EXIST: Folder already exists in target folder";
    case ECONA_FOLDER_NOT_FOUND: return "ECONA_FOLDER_NOT_FOUND: Folder does not exist in target folder";
    case ECONA_FOLDER_NO_PERMISSION: return "ECONA_FOLDER_NO_PERMISSION: Not allowed to perform required operation to folder in Device";
    case ECONA_FOLDER_NOT_EMPTY: return "ECONA_FOLDER_NOT_EMPTY: Not allowed to perform required operation because folder is not empty";
    case ECONA_FOLDER_NO_PERMISSION_ON_PC: return "ECONA_FOLDER_NO_PERMISSION_ON_PC: Not allowed to perform required operation to folder in PC";

// Application Installation:
    case ECONA_DEVICE_INSTALLER_BUSY: return "ECONA_DEVICE_INSTALLER_BUSY: Can not start Device's installer";

    default: return stringformat("Undefined error code: %08lx", error); // shouldn't occur
    }
}

//===================================================================
// DWORD2MediaString --  Returns name of the media for given DWORD
//
//
//===================================================================
std::string DWORD2MediaString(DWORD media)
{
    switch(media)
    {
    case CONAPI_MEDIA_IRDA: return "IrDA";
    case CONAPI_MEDIA_SERIAL: return "Serial";
    case CONAPI_MEDIA_BLUETOOTH: return "Bluetooth";
    case CONAPI_MEDIA_USB: return "USB";
    default: return stringformat("Unknown media: %08lx", media); // shouldn't occur
    }
}

//===================================================================
// DWORD2FSFunctionString --  Returns name of the file system function for given DWORD
//
//
//===================================================================
std::string DWORD2FSFunctionString(DWORD dwFSFunction)
{
    switch(dwFSFunction)
    {
    case CONARefreshDeviceMemoryValuesNtf: return "CONARefreshDeviceMemoryValuesNtf";
    case CONASetCurrentFolderNtf: return "CONASetCurrentFolderNtf";
    case CONAFindBeginNtf: return "CONAFindBeginNtf";
    case CONACreateFolderNtf: return "CONACreateFolderNtf";
    case CONADeleteFolderNtf: return "CONADeleteFolderNtf";
    case CONARenameFolderNtf: return "CONARenameFolderNtf";
    case CONAGetFileInfoNtf: return "CONAGetFileInfoNtf";
    case CONADeleteFileNtf: return "CONADeleteFileNtf";
    case CONAMoveFileNtf: return "CONAMoveFileNtf";
    case CONACopyFileNtf: return "CONACopyFileNtf";
    case CONARenameFileNtf: return "CONARenameFileNtf";
    case CONAReadFileNtf: return "CONAReadFileNtf";
    case CONAWriteFileNtf: return "CONAWriteFileNtf";
    case CONAConnectionLostNtf: return "CONAConnectionLostNtf";
    case CONAInstallApplicationNtf: return "CONAInstallApplicationNtf";
    default: return stringformat("Unknown FSFunction: %08lx", dwFSFunction); // shouldn't occur
    }
}

//===================================================================
// Permissions2String
// 
// Converts file attributes to string
// 
//===================================================================
std::string Permissions2String(DWORD dwAttributes)
{
    StringList list;
    if (dwAttributes & CONA_FPERM_READ)
        list.push_back("R");
    if (dwAttributes & CONA_FPERM_WRITE)
        list.push_back("W");
    if (dwAttributes & CONA_FPERM_DELETE)
        list.push_back("D");
    if (dwAttributes & CONA_FPERM_FOLDER)
        list.push_back("_Folder");
    if (dwAttributes & CONA_FPERM_DRIVE)
        list.push_back("_Drive");

    DWORD known= CONA_FPERM_READ|CONA_FPERM_WRITE|CONA_FPERM_DELETE|CONA_FPERM_FOLDER|CONA_FPERM_DRIVE;
    if (dwAttributes & ~known)
        list.push_back(stringformat("_FPERM_x%08lx", dwAttributes & ~known));
    return JoinStringList(list, "");
}


//===================================================================
// TrustedInfo2String
// 
// Converts file attributes to string
// 
//===================================================================
std::string TrustedInfo2String( DWORD dwTrustedInfo)
{
    StringList strTrustedInfo;
    if( CONAPI_IS_DEVICE_UNPAIRED( dwTrustedInfo))
        list.push_back("Unpaired");
    else if( CONAPI_IS_DEVICE_PAIRED( dwTrustedInfo))
        list.push_back("Paired");

    if( CONAPI_IS_PCSUITE_TRUSTED( dwTrustedInfo))
        list.push_back("Trusted");
    else
        list.push_back("Not trusted");

    return JoinStringList(list, ",");
}

