/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 */

// This file intends to prevent Windows from throwing up error boxes and
// offering to debug when serious errors happen. The errors are displayed
// on stderr instead. The purpose of this is to allow the tests to proceed
// scripted and catch the text for logging. If this behavior is desired,
// include this file with the executable being built. If the default
// behaviors are desired, don't include this file in the build.

#if defined(_MSC_VER)
#include <crtdbg.h>
#endif
#include <windows.h>
#include <iostream>

namespace qpid {
namespace tests {
namespace windows {

// Instead of popping up a window for exceptions, just print something out
LONG _stdcall UnhandledExceptionFilter (PEXCEPTION_POINTERS pExceptionInfo)
{
    DWORD dwExceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode;

    if (dwExceptionCode == EXCEPTION_ACCESS_VIOLATION)
        std::cerr << "\nERROR: ACCESS VIOLATION\n" << std::endl;
    else
        std::cerr << "\nERROR: UNHANDLED EXCEPTION\n" << std::endl;

    return EXCEPTION_EXECUTE_HANDLER;
}

struct redirect_errors_to_stderr {
    redirect_errors_to_stderr ();
};

static redirect_errors_to_stderr block;

redirect_errors_to_stderr::redirect_errors_to_stderr()
{
#if defined(_MSC_VER)
    _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
#endif

    // Prevent the system from displaying the critical-error-handler
    // and can't-open-file message boxes.
    SetErrorMode(SEM_FAILCRITICALERRORS);
    SetErrorMode(SEM_NOOPENFILEERRORBOX);

    // And this will catch all unhandled exceptions.
    SetUnhandledExceptionFilter (&UnhandledExceptionFilter);
}

}}}  // namespace
