using System;
using System.Runtime.InteropServices;
using System.Text;

namespace NetTunnelApp;

public delegate void HeartCallBack(string msg, uint timeStamp);

public enum ProtoCryptoType
{
    CRYPTO_NONE = 0,
    CRYPTO_BASE64 = 1,
    CRYPTO_AES128 = 2,
    CRYPTO_3DES = 3,
    CRYPTO_AES256 = 4
}

public enum LogLevel
{
    LOG_TRACE = 0,
    LOG_DEBUG,
    LOG_INFO,
    LOG_WARN,
    LOG_ERROR,
    LOG_CRITICAL,
    LOG_OFF
}

public enum NET_SHARE_MODE
{
    ///< Internet Share Mode(ICS) 模式
    ICS_SHARE_MODE = 0,

    ///< Net Address Translation(NAT) 模式
    NAT_SHARE_MODE = 1
};

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct VirtualMathineConfig
{
    ///< 用户虚拟机 ID
    public int vmId;

    ///< 用户虚拟机名称
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string vmName;

    ///< 用户服务端公钥
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string svrPublicKey;

    ///< 用户虚拟机网络地址
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
    public string vmNetwork;

    ///< 用户服务端接入网关
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string scgGateWay;

    ///< 用户服务端接入网关
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string scgTunnelGw;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct UserClientConfig
{
    ///< 用户接入网关控制 ID
    public int scgCtrlAppId;

    ///< 用户接入网关隧道 ID
    public int scgTunnelAppId;

    ///< 用户客户端私钥
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string cliPrivateKey;

    ///< 用户客户端公钥
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string cliPublicKey;

    ///< 用户客户端隧道IP地址
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
    public string cliAddress;

    ///< 用户虚拟机配置列表
    public IntPtr pVMConfig;

    ///< 用户虚拟机配置最大数
    public int tolVM;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct FilePath
{
    public int curUsed;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string CfgPath;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct NetCard
{
    public int IfIndex;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string UUID;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string Name;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 132)]
    public string Description;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
    public string IpAddr;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
    public string NetMask;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
    public string Gateway;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string MacAddr;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct WgSvrConfig
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string Name;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string Address;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string PrivateKey;

    public int ListenPort;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string CliPubKey;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string AllowNet;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct WgCliConfig
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string Name;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string PrivateKey;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string Address;


    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string SvrPubKey;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string AllowNet;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string ServerURL;
}

public class NetTunnelLib
{
    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int TunnelSDKInitEnv(String workDir, String svrUrl, String pLogFile, LogLevel level,
        bool isWorkServer);

    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern void TunnelSDKUnInit();
    
    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetAllNICInfo(out IntPtr netCard, ref int size);
    
    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetUserClientConfigure(String UserName, String token, out IntPtr userCfg);

    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int RemoteCtrlSvrCfgUserTunnel(int vmid, String cliNetwork);
    
    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int RemoteWireGuardControl(bool startOrStop);

    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int LocalWireGuardControl(bool startOrStop, bool checkPrivate = true);

    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int RemoteHeartControl(bool startOrStop, HeartCallBack cb);

    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern NET_SHARE_MODE GetCurrentNetShareMode();

    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern void SetCurrentNetShareMode(NET_SHARE_MODE shareMode);

    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int EnableSCGProxy(bool isEnable, String proxyIp, int proxyPort);

    [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern bool UsedSCGProxy();
}