#pragma once

#include "common.h"

#include <windows.h>

#define CFG_WIREGUARD_SECTION TEXT("WireGuard")
#define CFG_WIREGUARD_PATH    TEXT("WireGuardExe")
#define CFG_WGCFG_PATH        TEXT("WgCfgPath")
#define CFG_WG_PATH           TEXT("WgExe")

typedef struct {
    TCHAR path[MAX_PATH];
} FILE_PATH, *PFILE_PATH;

typedef struct {
    PFILE_PATH   pFilePath;
    unsigned int nItems;
} FILE_LIST, *PFILE_LIST;

/**
 * @brief IPv4 网络信息
 */
typedef struct {
    unsigned int prefix;                   ///< 网络前缀
    TCHAR        hostip[MAX_IP_LEN];       ///< IP 地址
    TCHAR        ip[MAX_IP_LEN];           ///< IP 地址
    TCHAR        network[MAX_IP_LEN];      ///< 网络地址
    TCHAR        broadcast[MAX_IP_LEN];    ///< 网络广播地址
    TCHAR        netmask[MAX_IP_LEN];      ///< 网络子网掩码
    TCHAR        hosts[64];                ///< number of hosts in text
    TCHAR        hostmin[MAX_IP_LEN];      ///< 最小网络主机 IP
    TCHAR        hostmax[MAX_IP_LEN];      ///< 最大网络主机 IP
} IP_INFO, *PIP_INFO;

#ifdef __cplusplus    // If used by C++ code,
extern "C" {
// we need to export the C interface
#endif

void RemoveTailLineBreak(TCHAR *pInputStr, int strSize);
int  RunCommand(TCHAR *pszCmd, TCHAR *pszResultBuffer, int dwResultBufferSize, unsigned long *pRetCode);

/**
 * @brief IPv4 子网掩码转 CIDR 掩码
 * @param[in] pNetMask IPv4 子网掩码字符串
 * @return IPv4 CIDR 掩码
 */
int __cdecl NetmaskToCIDR(const TCHAR *pNetMask);

/**
 * @brief CIDR 掩码转 IPv4 子网掩码
 * @param[in] cidr CIDR 掩码
 * @return CIDR 对应的子网掩码
 */
const TCHAR *CIDRToNetmask(const UINT8 cidr);

void   ShowWindowsErrorMessage(const TCHAR *pMsgHead);
void   StringReplaceAll(TCHAR *pOrigin, const TCHAR *pOldStr, const TCHAR *pNewStr);
void   StringRemoveAll(TCHAR *pOrigin, const TCHAR *pString);
TCHAR *binToHexString(TCHAR *p, const unsigned char *cp, unsigned int count);
int    GetWindowsServiceStatus(const TCHAR *pSvrName, PDWORD pStatus);
/**
 * @brief Unicode 宽字符串转 TCHAR 字符串
 * @param[in] pWStr  需要转换的宽字符串
 * @param[out] pOutStr 转换后的 TCHAR 字符串
 * @param[in] maxOutLen pOutStr 最大字节数
 * @return 函数执行结果 0: 成功， 小于0 失败 @see USER_ERRNO
 * - -ERR_INPUT_PARAMS 输入参数错误
 * - ERR_SUCCESS 成功
 */
int    WideCharToTChar(const WCHAR *pWStr, TCHAR *pOutStr, int maxOutLen);

/**
 * @brief  TCHAR 字符串 字符串转 Unicode 字符串
 * @param[in] pTStr 需要转换的 TCHAR 字符串
 * @param[out] pOutStr 转换后的 WCHAR 字符串
 * @param[in] maxOutLen pOutStr 最大字节数
 * @return 函数执行结果 0: 成功， 小于0 失败 @see USER_ERRNO
 * - -ERR_INPUT_PARAMS 输入参数错误
 * - ERR_SUCCESS 成功
 */
int TCharToWideChar(const TCHAR *pTStr, WCHAR *pOutStr, int maxOutLen);

int FindFile(const TCHAR *pPath, PFILE_LIST pFileList, const bool exitWhenMatchOne);
/**
 * @brief 计算 IPv4 网络信息
 * @param[in] pIpStr IPv4 地址
 * @param[in] pNetmask IPv4子网掩码
 * @param[out] pInfo 计算结果
 * @return 成功， 小于0 失败 @see USER_ERRNO
 * - -ERR_INPUT_PARAMS 输入参数错误
 * - -ERR_UN_SUPPORT 不支持的格式转换
 * - -ERR_MALLOC_MEMORY 分配内存失败
 * - ERR_SUCCESS 成功
 */
int GetIpV4InfoFromNetmask(const TCHAR *pIpStr, const TCHAR *pNetmask, PIP_INFO pInfo);
/**
 * @brief 计算 IPv4 网络信息
 * @param[in] pIpStr IPv4 网络信息 '/' 分割，支持CIDR以及子网掩码 example: 192.168.1.32/24, 192.168.1.32/255.255.255.0
 * @param[out] pInfo 计算结果
 * @return 0: 成功， 小于0 失败 @see USER_ERRNO
 * - -ERR_INPUT_PARAMS 输入参数错误
 * - -ERR_UN_SUPPORT 不支持的格式转换
 * - -ERR_MALLOC_MEMORY 分配内存失败
 * - ERR_SUCCESS 成功
 */
int GetIpV4InfoFromCIDR(const TCHAR *pIpStr, PIP_INFO pInfo);

int GetIpV4InfoFromHostname(int family, const char *host, PIP_INFO pInfo);

int InitializeWireGuardLibrary();
void UnInitializeWireGuardLibrary();

void StopUDPProxyServer();
int CreateUDPProxyServer();
#ifdef __cplusplus
}
#endif