#include "Utils/ProcessWin.h"

#include "include/base/cef_logging.h"

Process* Process::Create() {
    return new ProcessWin();
}

Process* Process::Create(const std::string& path, const std::string& args, const std::string& workDir) {
    return new ProcessWin(path, args, workDir);
}

ProcessWin::ProcessWin() : Process() {}

ProcessWin::ProcessWin(const std::string& path, const std::string& args, const std::string& workDir)
    : Process(path, args, workDir) {}

ProcessWin::~ProcessWin() {
    OnTerminate();
}

bool ProcessWin::OnExecute() {
    std::string command = path_ + " " + args_;

    STARTUPINFOA si{0};
    si.cb = sizeof(STARTUPINFO);
    bool sucess = CreateProcessA(nullptr, const_cast<LPSTR>(command.c_str()),
        nullptr, nullptr, false,
        0, nullptr,
        workDir_.empty() ? nullptr : workDir_.c_str(), &si, &info_);
    LOG(INFO)  << command << "(" << info_.dwProcessId << ")" << sucess;
    return sucess;
}

void ProcessWin::OnTerminate() {
    if (nullptr == info_.hProcess) {
        return;
    }

    if (TerminateProcess(info_.hProcess, 0)) {
        LOG(INFO) << path_ << "(" << info_.dwProcessId << ") success" ;
    } else {
        LOG(ERROR) << path_ << "(" << info_.dwProcessId << ") failed, errorCode:" << GetLastError();
    }
    CloseHandle(info_.hThread);
    ::WaitForSingleObject(info_.hProcess, INFINITE);
    CloseHandle(info_.hProcess);    
    info_.hProcess = nullptr;
}