/* myTestDll_test.c */

/* Tests to call functions in myTestDll.dll*/

// Copyright 2025 David Ireland, DI Management Services Pty Limited
// <www.di-mgt.com.au> <www.cryptosys.net>.
// Use of this source code is governed by the Apache License 2.0
// available at https://opensource.org/license/apache-2-0

/*
COMPILING
---------
WINDOWS: link to the library file `myTestDll.lib`.
In MSVC++ IDE, use
Project > Properties > Linker> Input > Additional Dependencies and add the full path to `myTestDll.lib`.
E.g.
Additional Dependencies = $(OutDir)myTestDll.lib;%(AdditionalDependencies)

Using MSVC command-line:
> CL myTestDll_test.c /link "path\to\myTestDll.lib"

Using MinGW (64-bit version)
> gcc -o myTestDll_test myTestDll_test.c "path\to\x64\myTestDll.lib"
*/

#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>  // For Unicode UTF16 characters
#ifdef NDEBUG
/* Make sure assertion testing is turned on */
#undef NDEBUG
#endif
#include <assert.h>

#include "myTestDll.h"

// Print bytes in hex form
void pr_bytes(const unsigned char *bytes, unsigned nbytes) {
    unsigned i;
    if (!bytes) return;
    for (i = 0; i < nbytes; i++) {
        printf("%02X ", bytes[i]);
    }
    printf("\n");
}

// Print wide-char string in hex form
void pr_wcstr(LPCWSTR wcstr) {
    size_t i, len;
    if (!wcstr) return;
    len = wcslen(wcstr);
    for (i = 0; i < len; i++) {
        printf("%04X ", wcstr[i]);
    }
    printf("\n");
}

int main(void)
{
    char *szIn = "Hello world!";
    unsigned char bytesIn[] = { 0xde, 0xad, 0xbe, 0xef };
    long r, n, nchars, nbytes, nwchars;
    char *strbuf = NULL;
    unsigned char *bbuf = NULL;
    // Unicode UTF16
    LPCWSTR utf16str= L"Unicode: Привет 世界";
    LPWSTR wbuf = NULL;
    
    r = MyVoidFunc();
    printf("MyVoidFunc returns %ld\n", r);

    n = -123;
    r = MyIntFunc(n);
    printf("MyIntFunc(%ld) returns %ld\n", n, r);

    nchars = MyStringFunc(NULL, 0, szIn, 0);
    printf("MyStringFunc returns %ld\n", nchars);
    assert(nchars >= 0);

    strbuf = malloc(nchars + 1);    // NB +1 for string
    nchars = MyStringFunc(strbuf, nchars, szIn, 0);
    assert(nchars >= 0);
    printf("MyStringFunc output is \"%s\"\n", strbuf);

    nbytes = MyByteFunc(NULL, 0, bytesIn, sizeof(bytesIn), 0xFEFF);
    assert(nbytes >= 0);
    printf("MyByteFunc returns %ld\n", nbytes);

    bbuf = malloc(nbytes);    // NB exact length for byte array
    nbytes = MyByteFunc(bbuf, nbytes, bytesIn, sizeof(bytesIn), 0xFEFF);
    assert(nbytes >= 0);
    printf("MyByteFunc returns (0x) ");
    pr_bytes(bbuf, nbytes);

    // Will display "???" in windows console
    wprintf(L"\"%s\"\n", utf16str);
    pr_wcstr(utf16str);

    nwchars = MyUnicodeFunc(NULL, 0, utf16str, 888);
    printf("MyUnicodeFunc(NULL) returns %ld\n", nwchars);
    assert(nwchars >= 0);

    wbuf = calloc(nwchars + 1, sizeof(wchar_t));  // +1 for terminating null
    nchars = MyUnicodeFunc(wbuf, nwchars, utf16str, 888);

    wprintf(L"\"%s\"\n", wbuf);
    pr_wcstr(wbuf);


    free(strbuf);
    free(bbuf);
    free(wbuf);

    return 0;
}