#include "pch.h"
#include "CppUnitTest.h"

#include "sccsdk.h"
#include <strsafe.h>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace TestNetTunnelSDK {
TEST_MODULE_INITIALIZE(ModuleInitialize) {
    const TCHAR *path = TEXT(
        "C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_windows\\NetTunnelApp\\bin\\Debug");

    Logger::WriteMessage("In Module Initialize");
    Assert::AreEqual(0,
                     TunnelSDKInitEnv(path,
                                      "http://172.21.40.39:32549",
                                      TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_"
                                           "windows\\NetTunnelApp\\bin\\Debug\\utest.log"),
                                      LOG_TRACE,
                                      false));
    //Assert::AreEqual(0, EnableVerifySignature(TEXT("123"), TEXT("123456")));
    //Assert::AreEqual(0, EnableSCGProxy(true, TEXT("efc.xajhuang.com"), 10001));
}

TEST_MODULE_CLEANUP(ModuleCleanup) {
    Logger::WriteMessage("In Module Cleanup");
    TunnelSDKUnInit();
}

TEST_CLASS(TestNetTunnelSDK) {
public:
    const int RET_OK = ERR_SUCCESS;

    TEST_METHOD(TestRunPipeCmd) {
#if 0
            TCHAR buf[1024];
            int ret = ERR_SUCCESS;
            DWORD retCode;

            Assert::AreEqual(ret, RunCommand(TEXT("cmd.exe /C dir E:\\"), buf, 1024, &retCode));
            Logger::WriteMessage("Return:");
            Logger::WriteMessage(buf);
#endif
    }

    TEST_METHOD(TestGetAllNICInfo) {
        PNIC_CONTENT pInfo = nullptr;

        int size = 0;

        Assert::AreEqual(RET_OK, GetAllNICInfo(&pInfo, &size));
        Assert::IsNotNull(pInfo);
        Assert::AreNotEqual(0, size);

        free(pInfo);
    }

#if 0
    TEST_METHOD(TestSetInterfaceIpAddressFromCIDR) {
        Assert::AreEqual(RET_OK, SetInterfaceIpAddressFromCIDR(TEXT("wg_server"), TEXT("192.168.100.250/24")));
    }

    TEST_METHOD(TestSetInterfaceIpAddress) {
        Assert::AreEqual(RET_OK,
                         SetInterfaceIpAddress(TEXT("wg_server"), TEXT("192.168.101.250"), TEXT("255.255.0.0")));
    }

    TEST_METHOD(TestGetInterfaceIndexByName) {
        int index;
        Assert::AreEqual(RET_OK, GetInterfaceIndexByName(TEXT("wg_server"), &index));
    }

    TEST_METHOD(TestRemoveInterfaceIpAddress) {
        Assert::AreEqual(RET_OK, RemoveInterfaceIpAddress(TEXT("wg_server")));
    }

    TEST_METHOD(TestGetWindowsHyperVStatus) {
        int enable;
        Assert::AreEqual(RET_OK, GetWindowsHyperVStatus(&enable));
        Assert::AreEqual(TRUE, enable);
    }

    TEST_METHOD(TestInstallWindowsNATCommand) {
        Assert::AreEqual(RET_OK, InstallWindowsNATCommand());
    }       

    TEST_METHOD(TestIsInterfacePrivate) {
        bool bRet;
        Assert::AreNotEqual(RET_OK, IsInterfacePrivate(TEXT("wg_cli_123"), &bRet));

        Assert::AreEqual(RET_OK, SetInterfacePrivate(TEXT("wg_cli"), true));
        Assert::AreEqual(RET_OK, IsInterfacePrivate(TEXT("wg_cli"), &bRet));
        Assert::AreEqual(true, bRet);

        Assert::AreEqual(RET_OK, SetInterfacePrivate(TEXT("wg_cli"), false));
        Assert::AreEqual(RET_OK, IsInterfacePrivate(TEXT("wg_cli"), &bRet));
        Assert::AreEqual(false, bRet);
    }

    TEST_METHOD(TestSetInterfacePrivate) {
        Assert::AreEqual(RET_OK, SetInterfacePrivate(TEXT("wg_cli_435"), true));
    }    
    

    TEST_METHOD(TestWireGuardNetConnectionSharingEnable) {
        Assert::AreEqual(RET_OK, WireGuardNetConnectionSharingEnable());
    }

    TEST_METHOD(TestCalcFileHash) {
        TCHAR outHash[MAX_PATH] = {0};

        Assert::AreEqual(RET_OK, CalcFileHash(HASH_SHA256, TEXT("E:\\wireguard.psm1"), outHash));
        Assert::AreEqual(TEXT("3ef17a2eb23a148a3fbe14cb4ef38747e0a1e5037b6afa2350a9b18f617bb5db"), outHash);
    }

    TEST_METHOD(TestWireGuardInstallServerService) {
        Assert::AreEqual(RET_OK, WireGuardInstallDefaultServerService(true));
    }

    TEST_METHOD(TestGetInternetConnectAdaptersIndex) {
        bool bRet;
        Assert::AreEqual(RET_OK, IsInternetConnectAdapter(9, &bRet));
        Assert::AreEqual(true, bRet);

        Assert::AreEqual(RET_OK, IsInternetConnectAdapter(44, &bRet));
        Assert::AreEqual(false, bRet);
    }

    TEST_METHOD(TestGetNetConnectionNetworkCategory) {
        bool chkStatus = false;
        Assert::AreEqual(RET_OK, GetNetConnectionNetworkCategory(TEXT("admin"), &chkStatus));
    }

    TEST_METHOD(TestWaitNetAdapterConnected) {
        Assert::AreEqual(RET_OK, WaitNetAdapterConnected(TEXT("admin"), 10 * 1000));
    }

    TEST_METHOD(TestProtoGetUserConfigure) {
        //Assert::AreEqual(RET_OK, ProtoGetUserConfigure("admin", "asfdsafdladf083asldf+="));
    }

    TEST_METHOD(TestAddRouteTable) {
        Assert::AreEqual(RET_OK, AddRouteTable(TEXT("1.1.1.1"), TEXT("255.255.255.0"), TEXT("10.10.10.1")));
    }

    TEST_METHOD(TestGetInterfaceGUIDByName) {
        GUID guid;

        Assert::AreEqual(RET_OK, GetInterfaceGUIDByName(TEXT("admin"), &guid));
        Assert::AreNotEqual(0, static_cast<int>(guid.Data1));

        //Assert::AreEqual(RET_OK, ProtoGetUserConfigure("admin", "asfdsafdladf083asldf+="));
    }

    TEST_METHOD(TestSetNATRule) {
        Assert::AreEqual(RET_OK, SetNATRule(TEXT("admin"), TEXT("10.10.10.250/24")));
    }

    TEST_METHOD(TestRemoveNATRule) {
        Assert::AreEqual(RET_OK, RemoveNATRule(TEXT("admin")));
    }

    TEST_METHOD(TestGetInterfaceIfIndexByIpAddr) {
        ULONG index = -1;
        Assert::AreEqual(RET_OK, GetInterfaceIfIndexByIpAddr(TEXT("10.10.10.1"), &index));
        Assert::AreNotEqual(-1, static_cast<int>(index));
    }

    TEST_METHOD(TestGetWireGuradTunnelInfo) {

        Assert::AreEqual(RET_OK, GetWireGuradTunnelInfo(TEXT("admin")));

        //Assert::AreEqual(RET_OK, RemoteWireGuardControl(false));
        //Assert::AreEqual(RET_OK, LocalWireGuardControl(false, false));
    }
#endif

    TEST_METHOD(TestIsWireGuardServerRunning) {
        bool bRet;
        Assert::AreEqual(RET_OK, IsWireGuardServerRunning(TEXT("tunnel_svr"), &bRet));
        Assert::AreEqual(false, bRet);
    }

    TEST_METHOD(TestGetNetConnectionSharing) {
        //bool chkStatus;
        //Assert::AreEqual(RET_OK, GetNetIntelnetConnectionSharing(TEXT("admin"), &chkStatus));
        //Assert::IsTrue(chkStatus);
    }

    TEST_METHOD(TestSetNetConnectionNetworkCategory) {
        //Assert::AreEqual(RET_OK, SetNetConnectionNetworkCategory());
    }

    TEST_METHOD(TestUserLogin) {
        PUSER_CLIENT_CONFIG pCfg;
        Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("1689189114026041344"), &pCfg));
    }

    TEST_METHOD(TestClientProgress) {
        PUSER_CLIENT_CONFIG pCfg = nullptr;
        Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("1323245235"), &pCfg));
        Assert::IsNotNull(pCfg);

        Assert::AreEqual(RET_OK, RemoteCtrlSvrCfgUserTunnel(2, TEXT("172.18.2.0/24")));
        Assert::AreEqual(RET_OK, RemoteWireGuardControl(true));
        Assert::AreEqual(RET_OK, LocalWireGuardControl(true, true));

        //EnableSCGProxy(true, 10000);

        //Sleep(30 * 1000);
        Assert::AreEqual(RET_OK, LocalWireGuardControl(false, false));
        Assert::AreEqual(RET_OK, RemoteWireGuardControl(false));        
    }

    TEST_METHOD(TestClientProgressFree) {
        Assert::AreEqual(RET_OK, LocalWireGuardControl(false, false));
        Assert::AreEqual(RET_OK, RemoteWireGuardControl(false));        
    }

    TEST_METHOD(TestGetSDKErrorMessage) {
        const CHAR *pErrStr = GetSDKErrorMessage(ERR_INPUT_PARAMS);
        Assert::AreEqual(pErrStr, "ERR_INPUT_PARAMS");
    }
};
}