#include "pch.h"
#include "CppUnitTest.h"
#include "../NetTunnelSDK/tunnel.h"
#include "../NetTunnelSDK/usrerr.h"
#include "../NetTunnelSDK/misc.h"
#include "../NetTunnelSDK/globalcfg.h"
#include "../NetTunnelSDK/network.h"
#include "../NetTunnelSDK/user.h"
#include "../NetTunnelSDK/protocol.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://localhost:9276", false));

    InitTunnelSDKLog(TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_"
                          "windows\\NetTunnelApp\\bin\\Debug\\utest.log"),
                     LOG_DEBUG);
}

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

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

    TEST_METHOD(TestFindWireguardExe) {
        Assert::AreEqual(RET_OK, FindWireguardExe(nullptr, 0));
    }

    TEST_METHOD(TestSetWireguardPath) {
        Assert::AreEqual(RET_OK, SetWireguardPath(TEXT("C:\\Program Files\\WireGuard\\wireguard.exe")));
    }

    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());
    }
#endif

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

    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(10, &bRet));
        Assert::AreEqual(true, bRet);

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

    TEST_METHOD(TestEnableNetConnectionSharing) {
        Assert::AreEqual(RET_OK, SetNetConnectionSharing(TEXT("wg_cli"), true, true));
        Assert::AreEqual(RET_OK, SetNetConnectionSharing(TEXT("wg_cli"), false, true));
    }

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

    TEST_METHOD(TestUserLogin) {
        //Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("123455")));
        
    }

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

    TEST_METHOD(TestSetClientConfige) {
        Assert::AreEqual(RET_OK, 
            SetClientConfige("6BWnmkCJqJC5iNoCEZWTxwGNG7qwkxFoVgAk4DoIKCk=", 
                "192.168.100.210/24", "10.10.10.1"));
    }    
};
}