/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*-
 * ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
 * Editor Settings: expandtabs and use 4 spaces for indentation */
/*
 * Copyright Likewise Software
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the license, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.  You should have received a copy
 * of the GNU Lesser General Public License along with this program.  If
 * not, see <http://www.gnu.org/licenses/>.
 *
 * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
 * TERMS AS WELL.  IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
 * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
 * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
 * LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE.  IF YOU
 * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
 * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
 * license@likewisesoftware.com
 */

/*
 * Authors: David Leimbach <dleimbach@likewise.com>
 */

#include <moonunit/moonunit.h>
#include <locale.h>
#include "lw/rtlstring.h"

MU_FIXTURE_SETUP(RtlWC16)
{
    MU_TIMEOUT(10000);
    setlocale(LC_ALL, "en_US.UTF-8");
}

MU_TEST(RtlWC16, wc16_simple)
{
    PWSTR string = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "42"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%d", 42), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlWC16StringFree(&expected);
}

MU_TEST(RtlWC16, cstring_wc16)
{
    WCHAR string[] = {0x91, 0x92, 0x3c5, 0};
    PSTR message = NULL;
    CHAR expected[] = {0xc2, 0x91, 0xc2, 0x92, 0xcf, 0x85, 0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlCStringAllocateFromWC16String(&message, string), 0);

    MU_ASSERT(RtlCStringIsEqual(message, expected, 1));

    RtlCStringFree(&message);
}

MU_TEST(RtlWC16, wc16_cstring)
{
    CHAR string[] = {0xc2, 0x91, 0xc2, 0x92, 0xcf, 0x85, 0};
    PWSTR message = NULL;
    WCHAR expected[] = {0x91, 0x92, 0x3c5, 0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&message, string), STATUS_SUCCESS);

    MU_ASSERT(RtlWC16StringIsEqual(message, expected, 1));

    RtlWC16StringFree(&message);
}

MU_TEST(RtlWC16, wc16_null)
{
    PWSTR string = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "(null)"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%s", (char *)0), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlWC16StringFree(&expected);
}

MU_TEST(RtlWC16, wc16_nil)
{
    PWSTR string = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, sizeof(size_t) == 4 ? "00000000" : "0000000000000000"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%p", (void *)0), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlWC16StringFree(&expected);
}

MU_TEST(RtlWC16, wc16_wc16)
{
    PWSTR string = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%ws", expected), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlWC16StringFree(&expected);
}

MU_TEST(RtlWC16, wc16_unicode)
{
    PWSTR string = {0};
    UNICODE_STRING message = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlUnicodeStringAllocateFromCString(&message, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%wZ", &message), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlWC16StringFree(&expected);
    RtlUnicodeStringFree(&message);
}

MU_TEST(RtlWC16, wc16_append_unicode)
{
    PWSTR string = {0};
    UNICODE_STRING string2 = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlUnicodeStringAllocateFromCString(&string2, "World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%s", "Hello"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateAppendPrintf(&string, " %wZ", &string2), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlUnicodeStringFree(&string2);
    RtlWC16StringFree(&expected);
}

MU_TEST(RtlWC16, wc16_ansi)
{
    PWSTR string = {0};
    ANSI_STRING message = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlAnsiStringAllocateFromCString(&message, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%Z", &message), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlAnsiStringFree(&message);
    RtlWC16StringFree(&expected);
}

MU_TEST(RtlWC16, wc16_append)
{
    PWSTR string = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%s", "Hello"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateAppendPrintf(&string, " %s", "World"), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlWC16StringFree(&expected);
}

MU_TEST(RtlWC16, wc16_append_ansi)
{
    PWSTR string = {0};
    ANSI_STRING string2 = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlAnsiStringAllocateFromCString(&string2, "World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocatePrintf(&string, "%s", "Hello"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateAppendPrintf(&string, " %Z", &string2), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlAnsiStringFree(&string2);
    RtlWC16StringFree(&expected);
}

MU_TEST(RtlWC16, wc16_append_to_null)
{
    PWSTR string = {0};
    PWSTR expected = {0};

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateFromCString(&expected, "Hello World"), 0);

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, RtlWC16StringAllocateAppendPrintf(&string, "%s %s", "Hello", "World"), 0);

    MU_ASSERT(RtlWC16StringIsEqual(expected, string, 1));

    RtlWC16StringFree(&string);
    RtlWC16StringFree(&expected);
}
