//===-- HostProcessWindows.cpp ----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/windows/windows.h"
#include "lldb/Host/windows/HostProcessWindows.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ConvertUTF.h"

#include <Psapi.h>

using namespace lldb_private;

namespace
{
struct MonitorInfo
{
    Host::MonitorChildProcessCallback callback;
    HANDLE process_handle;
};
}

HostProcessWindows::HostProcessWindows()
    : HostNativeProcessBase()
    , m_owns_handle(true)
{
}

HostProcessWindows::HostProcessWindows(lldb::process_t process)
    : HostNativeProcessBase(process)
    , m_owns_handle(true)
{
}

HostProcessWindows::~HostProcessWindows()
{
    Close();
}

void
HostProcessWindows::SetOwnsHandle(bool owns)
{
    m_owns_handle = owns;
}

Error HostProcessWindows::Terminate()
{
    Error error;
    if (m_process == nullptr)
        error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);

    if (!::TerminateProcess(m_process, 0))
        error.SetError(::GetLastError(), lldb::eErrorTypeWin32);

    return error;
}

Error HostProcessWindows::GetMainModule(FileSpec &file_spec) const
{
    Error error;
    if (m_process == nullptr)
        error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);

    std::vector<wchar_t> wpath(PATH_MAX);
    if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size()))
    {
        std::string path;
        if (llvm::convertWideToUTF8(wpath.data(), path))
            file_spec.SetFile(path, false);
        else
            error.SetErrorString("Error converting path to UTF-8");
    }
    else
        error.SetError(::GetLastError(), lldb::eErrorTypeWin32);

    return error;
}

lldb::pid_t HostProcessWindows::GetProcessId() const
{
    return (m_process == LLDB_INVALID_PROCESS) ? -1 : ::GetProcessId(m_process);
}

bool HostProcessWindows::IsRunning() const
{
    if (m_process == nullptr)
        return false;

    DWORD code = 0;
    if (!::GetExitCodeProcess(m_process, &code))
        return false;

    return (code == STILL_ACTIVE);
}

HostThread
HostProcessWindows::StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals)
{
    HostThread monitor_thread;
    MonitorInfo *info = new MonitorInfo;
    info->callback = callback;

    // Since the life of this HostProcessWindows instance and the life of the process may be different, duplicate the handle so that
    // the monitor thread can have ownership over its own copy of the handle.
    HostThread result;
    if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(), &info->process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
        result = ThreadLauncher::LaunchThread("ChildProcessMonitor", HostProcessWindows::MonitorThread, info, nullptr);
    return result;
}

lldb::thread_result_t
HostProcessWindows::MonitorThread(void *thread_arg)
{
    DWORD exit_code;

    MonitorInfo *info = static_cast<MonitorInfo *>(thread_arg);
    if (info)
    {
        ::WaitForSingleObject(info->process_handle, INFINITE);
        ::GetExitCodeProcess(info->process_handle, &exit_code);
        info->callback(::GetProcessId(info->process_handle), true, 0, exit_code);
        ::CloseHandle(info->process_handle);
        delete (info);
    }
    return 0;
}

void HostProcessWindows::Close()
{
    if (m_owns_handle && m_process != LLDB_INVALID_PROCESS)
        ::CloseHandle(m_process);
    m_process = nullptr;
}
