/*
  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.
*/

#if defined(_WIN32) && defined(_DEBUG)
#include "win_debug.hpp"

#ifndef USE_VISUAL_LEAK_DETECTOR
// Enable memory leak detection
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>

// Enable memory leak detection for new operator
#ifndef DBG_NEW
#define DBG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DBG_NEW
#endif

/**
 * Output the memory leak results to the console
 *
 * @param report_type Type of report (warn, error, or assert)
 * @param message message
 * @param error_code Error code
 * @return Result to return to CRT processing (1 will stop processing report)
 */
inline int __cdecl output_memory_leak_results(int report_type, char* message, int* error_code) {
  std::cerr << message;
  return 1;
}
#endif

void MemoryLeakListener::disable() {
#ifdef USE_VISUAL_LEAK_DETECTOR
  VLDDisable();
#else
  int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  flags &= ~_CRTDBG_ALLOC_MEM_DF;
  _CrtSetDbgFlag(flags);
#endif
}

void MemoryLeakListener::enable() {
#ifdef USE_VISUAL_LEAK_DETECTOR
  VLDEnable();
#else
  int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  flags |= _CRTDBG_ALLOC_MEM_DF;
  _CrtSetDbgFlag(flags);
#endif
}

#ifndef USE_VISUAL_LEAK_DETECTOR
void MemoryLeakListener::OnTestProgramStart(const testing::UnitTest& unit_test) {
  // Install the memory leak reporting
  _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, &output_memory_leak_results);
}

void MemoryLeakListener::OnTestProgramEnd(const testing::UnitTest& unit_test) {
  // Uninstall/Remove the memory leak reporting
  _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, &output_memory_leak_results);
}
#endif

void MemoryLeakListener::OnTestStart(const testing::TestInfo& test_information) {
#ifdef USE_VISUAL_LEAK_DETECTOR
  // Make all memory leaks (if any) as reported (clean slate)
  VLDMarkAllLeaksAsReported();
#else
  // Get the starting memory state
  _CrtMemCheckpoint(&memory_start_state_);
#endif

  // Enable memory leak detection
  enable();
}

void MemoryLeakListener::OnTestEnd(const testing::TestInfo& test_information) {
  // Check for memory leaks if the test was successful
  if (test_information.result()->Passed()) {
    check_leaks(test_information);
  }
}

void MemoryLeakListener::check_leaks(const testing::TestInfo& test_information) {
  // Disable memory leak checking
  disable();

#ifdef USE_VISUAL_LEAK_DETECTOR
  // Determine if a difference exists (e.g. leak)
  if (VLDGetLeaksCount() > 0) {
    VLDReportLeaks();
    VLDMarkAllLeaksAsReported();
#else
  // Get the ending memory state for the test
  _CrtMemState memory_end_state;
  _CrtMemCheckpoint(&memory_end_state);
  _CrtMemState memory_state_difference;

  // Determine if a difference exists (e.g. leak)
  if (_CrtMemDifference(&memory_state_difference, &memory_start_state_, &memory_end_state)) {
    _CrtMemDumpAllObjectsSince(&memory_start_state_);
    _CrtMemDumpStatistics(&memory_state_difference);
#endif
    FAIL() << "Memory leaks detected in " << test_information.test_case_name() << "."
           << test_information.name();
  }
}

#endif
