/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#include "platform-posix.h"

#include "openthread/platform/uart.h"
#include "utils/code_utils.h"

static HANDLE s_WorkerThread;
static HANDLE s_StopWorkerEvent;

DWORD WINAPI 
windowsUartWorkerThread(
    _In_ LPVOID lpThreadParameter
    )
{
    DWORD originalConsoleMode;
    HANDLE waitHandles[] = { s_StopWorkerEvent, GetStdHandle(STD_INPUT_HANDLE) };
    uint8_t ch;
    
    // Cache the original console mode
    GetConsoleMode(waitHandles[1], &originalConsoleMode);

    // Fake the first new line
    ch = '\n';
    otPlatUartReceived(&ch, 1);

    // Wait for console events
    while (WaitForMultipleObjects(ARRAYSIZE(waitHandles), waitHandles, FALSE, INFINITE) == WAIT_OBJECT_0 + 1)
    {
        DWORD numberOfEvent = 0;
        if (GetNumberOfConsoleInputEvents(waitHandles[1], &numberOfEvent))
        {
            for (; numberOfEvent > 0; numberOfEvent--)
            {
                INPUT_RECORD record;
                DWORD numRead;
                if (!ReadConsoleInput(waitHandles[1], &record, 1, &numRead) ||
                    record.EventType != KEY_EVENT ||
                    !record.Event.KeyEvent.bKeyDown)
                    continue;
                
                ch = (uint8_t)record.Event.KeyEvent.uChar.AsciiChar;
                otPlatUartReceived(&ch, 1);
            }
        }
    }

    return NO_ERROR;
}

otError otPlatUartEnable(void)
{
    otError error = OT_ERROR_NONE;

    // Create the worker thread stop event
    otEXPECT_ACTION((s_StopWorkerEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL, error = OT_ERROR_GENERIC);

    // Start the worker thread
    otEXPECT_ACTION((s_WorkerThread = CreateThread(NULL, 0, windowsUartWorkerThread, NULL, 0, NULL)) != NULL,
		    error = OT_ERROR_GENERIC);

    return error;

exit:
    CloseHandle(s_StopWorkerEvent);
    s_StopWorkerEvent = NULL;
    return error;
}

otError otPlatUartDisable(void)
{
    otError error = OT_ERROR_NONE;

    // Set the shutdown event
    SetEvent(s_StopWorkerEvent);

    // Wait for the worker to compelte
    WaitForSingleObject(s_WorkerThread, INFINITE);
    
    CloseHandle(s_WorkerThread);
    s_WorkerThread = NULL;

    CloseHandle(s_StopWorkerEvent);
    s_StopWorkerEvent = NULL;

    return error;
}

otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
{
    otError error = OT_ERROR_NONE;

    DWORD dwNumCharsWritten = 0;
    otEXPECT_ACTION(WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), aBuf, aBufLength, &dwNumCharsWritten, NULL),
		    error = OT_ERROR_GENERIC);

    otPlatUartSendDone();

exit:
    return error;
}

void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
{
    // No-op on Windows
    UNREFERENCED_PARAMETER(aReadFdSet);
    UNREFERENCED_PARAMETER(aWriteFdSet);
    UNREFERENCED_PARAMETER(aErrorFdSet);
    UNREFERENCED_PARAMETER(aMaxFd);
}

void platformUartProcess(void)
{
    // No-op on Windows
}
