// Copyright Antony Polukhin, 2016-2019.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_STACKTRACE_DETAIL_FRAME_MSVC_IPP
#define BOOST_STACKTRACE_DETAIL_FRAME_MSVC_IPP

#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#   pragma once
#endif

#include <boost/stacktrace/frame.hpp>

#include <boost/core/demangle.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/stacktrace/detail/to_dec_array.hpp>
#include <boost/stacktrace/detail/to_hex_array.hpp>
#include <windows.h>
#include "dbgeng.h"

#ifdef BOOST_MSVC
#   pragma comment(lib, "ole32.lib")
#   pragma comment(lib, "Dbgeng.lib")
#endif


#ifdef __CRT_UUID_DECL // for __MINGW32__
    __CRT_UUID_DECL(IDebugClient,0x27fe5639,0x8407,0x4f47,0x83,0x64,0xee,0x11,0x8f,0xb0,0x8a,0xc8)
    __CRT_UUID_DECL(IDebugControl,0x5182e668,0x105e,0x416e,0xad,0x92,0x24,0xef,0x80,0x04,0x24,0xba)
    __CRT_UUID_DECL(IDebugSymbols,0x8c31e98c,0x983a,0x48a5,0x90,0x16,0x6f,0xe5,0xd6,0x67,0xa9,0x50)
#elif defined(DEFINE_GUID) && !defined(BOOST_MSVC)
    DEFINE_GUID(IID_IDebugClient,0x27fe5639,0x8407,0x4f47,0x83,0x64,0xee,0x11,0x8f,0xb0,0x8a,0xc8);
    DEFINE_GUID(IID_IDebugControl,0x5182e668,0x105e,0x416e,0xad,0x92,0x24,0xef,0x80,0x04,0x24,0xba);
    DEFINE_GUID(IID_IDebugSymbols,0x8c31e98c,0x983a,0x48a5,0x90,0x16,0x6f,0xe5,0xd6,0x67,0xa9,0x50);
#endif



// Testing. Remove later
//#   define __uuidof(x) ::IID_ ## x

namespace boost { namespace stacktrace { namespace detail {

class com_global_initer: boost::noncopyable {
    bool ok_;

public:
    com_global_initer() BOOST_NOEXCEPT
        : ok_(false)
    {
        // COINIT_MULTITHREADED means that we must serialize access to the objects manually.
        // This is the fastest way to work. If user calls CoInitializeEx before us - we 
        // can end up with other mode (which is OK for us).
        //
        // If we call CoInitializeEx befire user - user may end up with different mode, which is a problem.
        // So we need to call that initialization function as late as possible.
        const DWORD res = ::CoInitializeEx(0, COINIT_MULTITHREADED);
        ok_ = (res == S_OK || res == S_FALSE);
    }

    ~com_global_initer() BOOST_NOEXCEPT {
        if (ok_) {
            ::CoUninitialize();
        }
    }
};


template <class T>
class com_holder: boost::noncopyable {
    T* holder_;

public:
    com_holder(const com_global_initer&) BOOST_NOEXCEPT
        : holder_(0)
    {}

    T* operator->() const BOOST_NOEXCEPT {
        return holder_;
    }

    void** to_void_ptr_ptr() BOOST_NOEXCEPT {
        return reinterpret_cast<void**>(&holder_);
    }

    bool is_inited() const BOOST_NOEXCEPT {
        return !!holder_;
    }

    ~com_holder() BOOST_NOEXCEPT {
        if (holder_) {
            holder_->Release();
        }
    }
};


static std::string mingw_demangling_workaround(const std::string& s) {
#ifdef BOOST_GCC
    if (s.empty()) {
        return s;
    }

    if (s[0] != '_') {
        return boost::core::demangle(('_' + s).c_str());
    }

    return boost::core::demangle(s.c_str());
#else
    return s;
#endif
}

class debugging_symbols: boost::noncopyable {
    static void try_init_com(com_holder< ::IDebugSymbols>& idebug, const com_global_initer& com) BOOST_NOEXCEPT {
        com_holder< ::IDebugClient> iclient(com);
        if (S_OK != ::DebugCreate(__uuidof(IDebugClient), iclient.to_void_ptr_ptr())) {
            return;
        }

        com_holder< ::IDebugControl> icontrol(com);
        const bool res0 = (S_OK == iclient->QueryInterface(
            __uuidof(IDebugControl),
            icontrol.to_void_ptr_ptr()
        ));
        if (!res0) {
            return;
        }

        const bool res1 = (S_OK == iclient->AttachProcess(
            0,
            ::GetCurrentProcessId(),
            DEBUG_ATTACH_NONINVASIVE | DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND
        ));
        if (!res1) {
            return;
        }

        if (S_OK != icontrol->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE)) {
            return;
        }

        // No cheking: QueryInterface sets the output parameter to NULL in case of error.
        iclient->QueryInterface(__uuidof(IDebugSymbols), idebug.to_void_ptr_ptr());
    }

#ifndef BOOST_STACKTRACE_USE_WINDBG_CACHED

    boost::stacktrace::detail::com_global_initer com_;
    com_holder< ::IDebugSymbols> idebug_;
public:
    debugging_symbols() BOOST_NOEXCEPT
        : com_()
        , idebug_(com_)
    {
        try_init_com(idebug_, com_);
    }

#else

#ifdef BOOST_NO_CXX11_THREAD_LOCAL
#   error Your compiler does not support C++11 thread_local storage. It`s impossible to build with BOOST_STACKTRACE_USE_WINDBG_CACHED.
#endif

    static com_holder< ::IDebugSymbols>& get_thread_local_debug_inst() BOOST_NOEXCEPT {
        // [class.mfct]: A static local variable or local type in a member function always refers to the same entity, whether
        // or not the member function is inline.
        static thread_local boost::stacktrace::detail::com_global_initer com;
        static thread_local com_holder< ::IDebugSymbols> idebug(com);

        if (!idebug.is_inited()) {
            try_init_com(idebug, com);
        }

        return idebug;
    }

    com_holder< ::IDebugSymbols>& idebug_;
public:
    debugging_symbols() BOOST_NOEXCEPT
        : idebug_( get_thread_local_debug_inst() )
    {}

#endif // #ifndef BOOST_STACKTRACE_USE_WINDBG_CACHED

    bool is_inited() const BOOST_NOEXCEPT {
        return idebug_.is_inited();
    }

    std::string get_name_impl(const void* addr, std::string* module_name = 0) const {
        std::string result;
        if (!is_inited()) {
            return result;
        }
        const ULONG64 offset = reinterpret_cast<ULONG64>(addr);

        char name[256];
        name[0] = '\0';
        ULONG size = 0;
        bool res = (S_OK == idebug_->GetNameByOffset(
            offset,
            name,
            sizeof(name),
            &size,
            0
        ));

        if (!res && size != 0) {
            result.resize(size);
            res = (S_OK == idebug_->GetNameByOffset(
                offset,
                &result[0],
                static_cast<ULONG>(result.size()),
                &size,
                0
            ));
        } else if (res) {
            result = name;
        }

        if (!res) {
            result.clear();
            return result;
        }

        const std::size_t delimiter = result.find_first_of('!');
        if (module_name) {
            *module_name = result.substr(0, delimiter);
        }

        if (delimiter == std::string::npos) {
            // If 'delimiter' is equal to 'std::string::npos' then we have only module name.
            result.clear();
            return result;
        }

        result = mingw_demangling_workaround(
            result.substr(delimiter + 1)
        );

        return result;
    }

    std::size_t get_line_impl(const void* addr) const BOOST_NOEXCEPT {
        ULONG result = 0;
        if (!is_inited()) {
            return result;
        }

        const bool is_ok = (S_OK == idebug_->GetLineByOffset(
            reinterpret_cast<ULONG64>(addr),
            &result,
            0,
            0,
            0,
            0
        ));

        return (is_ok ? result : 0);
    }

    std::pair<std::string, std::size_t> get_source_file_line_impl(const void* addr) const {
        std::pair<std::string, std::size_t> result;
        if (!is_inited()) {
            return result;
        }
        const ULONG64 offset = reinterpret_cast<ULONG64>(addr);

        char name[256];
        name[0] = 0;
        ULONG size = 0;
        ULONG line_num = 0;
        bool res = (S_OK == idebug_->GetLineByOffset(
            offset,
            &line_num,
            name,
            sizeof(name),
            &size,
            0
        ));

        if (res) {
            result.first = name;
            result.second = line_num;
            return result;
        }

        if (!res && size == 0) {
            return result;
        }

        result.first.resize(size);
        res = (S_OK == idebug_->GetLineByOffset(
            offset,
            &line_num,
            &result.first[0],
            static_cast<ULONG>(result.first.size()),
            &size,
            0
        ));
        result.second = line_num;

        if (!res) {
            result.first.clear();
            result.second = 0;
        }

        return result;
    }

    void to_string_impl(const void* addr, std::string& res) const {
        if (!is_inited()) {
            return;
        }

        std::string module_name;
        std::string name = this->get_name_impl(addr, &module_name);
        if (!name.empty()) {
            res += name;
        } else {
            res += to_hex_array(addr).data();
        }

        std::pair<std::string, std::size_t> source_line = this->get_source_file_line_impl(addr);
        if (!source_line.first.empty() && source_line.second) {
            res += " at ";
            res += source_line.first;
            res += ':';
            res += boost::stacktrace::detail::to_dec_array(source_line.second).data();
        } else if (!module_name.empty()) {
            res += " in ";
            res += module_name;
        }
    }
};

std::string to_string(const frame* frames, std::size_t size) {
    boost::stacktrace::detail::debugging_symbols idebug;
    if (!idebug.is_inited()) {
        return std::string();
    }

    std::string res;
    res.reserve(64 * size);
    for (std::size_t i = 0; i < size; ++i) {
        if (i < 10) {
            res += ' ';
        }
        res += boost::stacktrace::detail::to_dec_array(i).data();
        res += '#';
        res += ' ';
        idebug.to_string_impl(frames[i].address(), res);
        res += '\n';
    }

    return res;
}

} // namespace detail

std::string frame::name() const {
    boost::stacktrace::detail::debugging_symbols idebug;
    return idebug.get_name_impl(addr_);
}


std::string frame::source_file() const {
    boost::stacktrace::detail::debugging_symbols idebug;
    return idebug.get_source_file_line_impl(addr_).first;
}

std::size_t frame::source_line() const {
    boost::stacktrace::detail::debugging_symbols idebug;
    return idebug.get_line_impl(addr_);
}

std::string to_string(const frame& f) {
    std::string res;

    boost::stacktrace::detail::debugging_symbols idebug;
    idebug.to_string_impl(f.address(), res);
    return res;
}

}} // namespace boost::stacktrace

#endif // BOOST_STACKTRACE_DETAIL_FRAME_MSVC_IPP
