// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "utils/PlatformDebugLogger.h"

#include "common/Assert.h"
#include "common/windows_with_undefs.h"

#include <array>
#include <thread>

namespace utils {

    class WindowsDebugLogger : public PlatformDebugLogger {
      public:
        WindowsDebugLogger() : PlatformDebugLogger() {
            if (IsDebuggerPresent()) {
                // This condition is true when running inside Visual Studio or some other debugger.
                // Messages are already printed there so we don't need to do anything.
                return;
            }

            mShouldExitHandle = CreateEventA(nullptr, TRUE, FALSE, nullptr);
            ASSERT(mShouldExitHandle != nullptr);

            mThread = std::thread(
                [](HANDLE shouldExit) {
                    // https://blogs.msdn.microsoft.com/reiley/2011/07/29/a-debugging-approach-to-outputdebugstring/
                    // for the layout of this struct.
                    struct {
                        DWORD process_id;
                        char data[4096 - sizeof(DWORD)];
                    }* dbWinBuffer = nullptr;

                    HANDLE file = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
                                                     0, sizeof(*dbWinBuffer), "DBWIN_BUFFER");
                    ASSERT(file != nullptr);
                    ASSERT(file != INVALID_HANDLE_VALUE);

                    dbWinBuffer = static_cast<decltype(dbWinBuffer)>(
                        MapViewOfFile(file, SECTION_MAP_READ, 0, 0, 0));
                    ASSERT(dbWinBuffer != nullptr);

                    HANDLE dbWinBufferReady =
                        CreateEventA(nullptr, FALSE, FALSE, "DBWIN_BUFFER_READY");
                    ASSERT(dbWinBufferReady != nullptr);

                    HANDLE dbWinDataReady = CreateEventA(nullptr, FALSE, FALSE, "DBWIN_DATA_READY");
                    ASSERT(dbWinDataReady != nullptr);

                    std::array<HANDLE, 2> waitHandles = {shouldExit, dbWinDataReady};
                    while (true) {
                        SetEvent(dbWinBufferReady);
                        DWORD wait = WaitForMultipleObjects(waitHandles.size(), waitHandles.data(),
                                                            FALSE, INFINITE);
                        if (wait == WAIT_OBJECT_0) {
                            break;
                        }
                        ASSERT(wait == WAIT_OBJECT_0 + 1);
                        fprintf(stderr, "%.*s\n", static_cast<int>(sizeof(dbWinBuffer->data)),
                                dbWinBuffer->data);
                        fflush(stderr);
                    }

                    CloseHandle(dbWinDataReady);
                    CloseHandle(dbWinBufferReady);
                    UnmapViewOfFile(dbWinBuffer);
                    CloseHandle(file);
                },
                mShouldExitHandle);
        }

        ~WindowsDebugLogger() override {
            if (IsDebuggerPresent()) {
                // This condition is true when running inside Visual Studio or some other debugger.
                // Messages are already printed there so we don't need to do anything.
                return;
            }

            if (mShouldExitHandle != nullptr) {
                BOOL result = SetEvent(mShouldExitHandle);
                ASSERT(result != 0);
                CloseHandle(mShouldExitHandle);
            }

            if (mThread.joinable()) {
                mThread.join();
            }
        }

      private:
        std::thread mThread;
        HANDLE mShouldExitHandle = INVALID_HANDLE_VALUE;
    };

    PlatformDebugLogger* CreatePlatformDebugLogger() {
        return new WindowsDebugLogger();
    }

}  // namespace utils
