/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmCallVisualStudioMacro.h"

#include <sstream>

#include "cmSystemTools.h"

#if defined(_MSC_VER)
#  define HAVE_COMDEF_H
#endif

// Just for this file:
//
static bool LogErrorsAsMessages;

#if defined(HAVE_COMDEF_H)

#  include <comdef.h>

// Copied from a correct comdef.h to avoid problems with deficient versions
// of comdef.h that exist in the wild... Fixes issue #7533.
//
#  ifdef _NATIVE_WCHAR_T_DEFINED
#    ifdef _DEBUG
#      pragma comment(lib, "comsuppwd.lib")
#    else
#      pragma comment(lib, "comsuppw.lib")
#    endif
#  else
#    ifdef _DEBUG
#      pragma comment(lib, "comsuppd.lib")
#    else
#      pragma comment(lib, "comsupp.lib")
#    endif
#  endif

//! Use ReportHRESULT to make a cmSystemTools::Message after calling
//! a COM method that may have failed.
#  define ReportHRESULT(hr, context)                                          \
    if (FAILED(hr)) {                                                         \
      if (LogErrorsAsMessages) {                                              \
        std::ostringstream _hresult_oss;                                      \
        _hresult_oss.flags(std::ios::hex);                                    \
        _hresult_oss << context << " failed HRESULT, hr = 0x" << hr           \
                     << std::endl;                                            \
        _hresult_oss.flags(std::ios::dec);                                    \
        _hresult_oss << __FILE__ << "(" << __LINE__ << ")";                   \
        cmSystemTools::Message(_hresult_oss.str());                           \
      }                                                                       \
    }

//! Using the given instance of Visual Studio, call the named macro
HRESULT InstanceCallMacro(IDispatch* vsIDE, const std::string& macro,
                          const std::string& args)
{
  HRESULT hr = E_POINTER;

  _bstr_t macroName(macro.c_str());
  _bstr_t macroArgs(args.c_str());

  if (0 != vsIDE) {
    DISPID dispid = (DISPID)-1;
    wchar_t execute_command[] = L"ExecuteCommand";
    OLECHAR* name = execute_command;

    hr =
      vsIDE->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid);
    ReportHRESULT(hr, "GetIDsOfNames(ExecuteCommand)");

    if (SUCCEEDED(hr)) {
      VARIANTARG vargs[2];
      DISPPARAMS params;
      VARIANT result;
      EXCEPINFO excep;
      UINT arg = (UINT)-1;

      // No VariantInit or VariantClear calls are necessary for
      // these two vargs. They are both local _bstr_t variables
      // that remain in scope for the duration of the Invoke call.
      //
      V_VT(&vargs[1]) = VT_BSTR;
      V_BSTR(&vargs[1]) = macroName;
      V_VT(&vargs[0]) = VT_BSTR;
      V_BSTR(&vargs[0]) = macroArgs;

      params.rgvarg = &vargs[0];
      params.rgdispidNamedArgs = 0;
      params.cArgs = sizeof(vargs) / sizeof(vargs[0]);
      params.cNamedArgs = 0;

      VariantInit(&result);

      memset(&excep, 0, sizeof(excep));

      hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
                         DISPATCH_METHOD, &params, &result, &excep, &arg);

      std::ostringstream oss;
      oss << std::endl;
      oss << "Invoke(ExecuteCommand)" << std::endl;
      oss << "  Macro: " << macro << std::endl;
      oss << "  Args: " << args << std::endl;

      if (DISP_E_EXCEPTION == hr) {
        oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << std::endl;
        oss << "  wCode: " << excep.wCode << std::endl;
        oss << "  wReserved: " << excep.wReserved << std::endl;
        if (excep.bstrSource) {
          oss << "  bstrSource: " << (const char*)(_bstr_t)excep.bstrSource
              << std::endl;
        }
        if (excep.bstrDescription) {
          oss << "  bstrDescription: "
              << (const char*)(_bstr_t)excep.bstrDescription << std::endl;
        }
        if (excep.bstrHelpFile) {
          oss << "  bstrHelpFile: " << (const char*)(_bstr_t)excep.bstrHelpFile
              << std::endl;
        }
        oss << "  dwHelpContext: " << excep.dwHelpContext << std::endl;
        oss << "  pvReserved: " << excep.pvReserved << std::endl;
        oss << "  pfnDeferredFillIn: "
            << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << std::endl;
        oss << "  scode: " << excep.scode << std::endl;
      }

      std::string exstr(oss.str());
      ReportHRESULT(hr, exstr.c_str());

      VariantClear(&result);
    }
  }

  return hr;
}

//! Get the Solution object from the IDE object
HRESULT GetSolutionObject(IDispatch* vsIDE, IDispatchPtr& vsSolution)
{
  HRESULT hr = E_POINTER;

  if (0 != vsIDE) {
    DISPID dispid = (DISPID)-1;
    wchar_t solution[] = L"Solution";
    OLECHAR* name = solution;

    hr =
      vsIDE->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid);
    ReportHRESULT(hr, "GetIDsOfNames(Solution)");

    if (SUCCEEDED(hr)) {
      DISPPARAMS params;
      VARIANT result;
      EXCEPINFO excep;
      UINT arg = (UINT)-1;

      params.rgvarg = 0;
      params.rgdispidNamedArgs = 0;
      params.cArgs = 0;
      params.cNamedArgs = 0;

      VariantInit(&result);

      memset(&excep, 0, sizeof(excep));

      hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
                         DISPATCH_PROPERTYGET, &params, &result, &excep, &arg);
      ReportHRESULT(hr, "Invoke(Solution)");

      if (SUCCEEDED(hr)) {
        vsSolution = V_DISPATCH(&result);
      }

      VariantClear(&result);
    }
  }

  return hr;
}

//! Get the FullName property from the Solution object
HRESULT GetSolutionFullName(IDispatch* vsSolution, std::string& fullName)
{
  HRESULT hr = E_POINTER;

  if (0 != vsSolution) {
    DISPID dispid = (DISPID)-1;
    wchar_t full_name[] = L"FullName";
    OLECHAR* name = full_name;

    hr = vsSolution->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                   &dispid);
    ReportHRESULT(hr, "GetIDsOfNames(FullName)");

    if (SUCCEEDED(hr)) {
      DISPPARAMS params;
      VARIANT result;
      EXCEPINFO excep;
      UINT arg = (UINT)-1;

      params.rgvarg = 0;
      params.rgdispidNamedArgs = 0;
      params.cArgs = 0;
      params.cNamedArgs = 0;

      VariantInit(&result);

      memset(&excep, 0, sizeof(excep));

      hr = vsSolution->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
                              DISPATCH_PROPERTYGET, &params, &result, &excep,
                              &arg);
      ReportHRESULT(hr, "Invoke(FullName)");

      if (SUCCEEDED(hr)) {
        fullName = (std::string)(_bstr_t)V_BSTR(&result);
      }

      VariantClear(&result);
    }
  }

  return hr;
}

//! Get the FullName property from the Solution object, given the IDE object
HRESULT GetIDESolutionFullName(IDispatch* vsIDE, std::string& fullName)
{
  IDispatchPtr vsSolution;
  HRESULT hr = GetSolutionObject(vsIDE, vsSolution);
  ReportHRESULT(hr, "GetSolutionObject");

  if (SUCCEEDED(hr)) {
    GetSolutionFullName(vsSolution, fullName);
    ReportHRESULT(hr, "GetSolutionFullName");
  }

  return hr;
}

//! Get all running objects from the Windows running object table.
//! Save them in a map by their display names.
HRESULT GetRunningInstances(std::map<std::string, IUnknownPtr>& mrot)
{
  // mrot == Map of the Running Object Table

  IRunningObjectTablePtr runningObjectTable;
  IEnumMonikerPtr monikerEnumerator;
  IMonikerPtr moniker;
  ULONG numFetched = 0;

  HRESULT hr = GetRunningObjectTable(0, &runningObjectTable);
  ReportHRESULT(hr, "GetRunningObjectTable");

  if (SUCCEEDED(hr)) {
    hr = runningObjectTable->EnumRunning(&monikerEnumerator);
    ReportHRESULT(hr, "EnumRunning");
  }

  if (SUCCEEDED(hr)) {
    hr = monikerEnumerator->Reset();
    ReportHRESULT(hr, "Reset");
  }

  if (SUCCEEDED(hr)) {
    while (S_OK == monikerEnumerator->Next(1, &moniker, &numFetched)) {
      std::string runningObjectName;
      IUnknownPtr runningObjectVal;
      IBindCtxPtr ctx;

      hr = CreateBindCtx(0, &ctx);
      ReportHRESULT(hr, "CreateBindCtx");

      if (SUCCEEDED(hr)) {
        LPOLESTR displayName = 0;
        hr = moniker->GetDisplayName(ctx, 0, &displayName);
        ReportHRESULT(hr, "GetDisplayName");
        if (displayName) {
          runningObjectName = (std::string)(_bstr_t)displayName;
          CoTaskMemFree(displayName);
        }

        hr = runningObjectTable->GetObject(moniker, &runningObjectVal);
        ReportHRESULT(hr, "GetObject");
        if (SUCCEEDED(hr)) {
          mrot.insert(std::make_pair(runningObjectName, runningObjectVal));
        }
      }

      numFetched = 0;
      moniker = 0;
    }
  }

  return hr;
}

//! Do the two file names refer to the same Visual Studio solution? Or are
//! we perhaps looking for any and all solutions?
bool FilesSameSolution(const std::string& slnFile, const std::string& slnName)
{
  if (slnFile == "ALL" || slnName == "ALL") {
    return true;
  }

  // Otherwise, make lowercase local copies, convert to Unix slashes, and
  // see if the resulting strings are the same:
  std::string s1 = cmSystemTools::LowerCase(slnFile);
  std::string s2 = cmSystemTools::LowerCase(slnName);
  cmSystemTools::ConvertToUnixSlashes(s1);
  cmSystemTools::ConvertToUnixSlashes(s2);

  return s1 == s2;
}

//! Find instances of Visual Studio with the given solution file
//! open. Pass "ALL" for slnFile to gather all running instances
//! of Visual Studio.
HRESULT FindVisualStudioInstances(const std::string& slnFile,
                                  std::vector<IDispatchPtr>& instances)
{
  std::map<std::string, IUnknownPtr> mrot;

  HRESULT hr = GetRunningInstances(mrot);
  ReportHRESULT(hr, "GetRunningInstances");

  if (SUCCEEDED(hr)) {
    std::map<std::string, IUnknownPtr>::iterator it;
    for (it = mrot.begin(); it != mrot.end(); ++it) {
      if (cmSystemTools::StringStartsWith(it->first.c_str(),
                                          "!VisualStudio.DTE.")) {
        IDispatchPtr disp(it->second);
        if (disp != (IDispatch*)0) {
          std::string slnName;
          hr = GetIDESolutionFullName(disp, slnName);
          ReportHRESULT(hr, "GetIDESolutionFullName");

          if (FilesSameSolution(slnFile, slnName)) {
            instances.push_back(disp);

            // std::cout << "Found Visual Studio instance." << std::endl;
            // std::cout << "  ROT entry name: " << it->first << std::endl;
            // std::cout << "  ROT entry object: "
            //          << (IUnknown*) it->second << std::endl;
            // std::cout << "  slnFile: " << slnFile << std::endl;
            // std::cout << "  slnName: " << slnName << std::endl;
          }
        }
      }
    }
  }

  return hr;
}

#endif // defined(HAVE_COMDEF_H)

int cmCallVisualStudioMacro::GetNumberOfRunningVisualStudioInstances(
  const std::string& slnFile)
{
  int count = 0;

  LogErrorsAsMessages = false;

#if defined(HAVE_COMDEF_H)
  HRESULT hr = CoInitialize(0);
  ReportHRESULT(hr, "CoInitialize");

  if (SUCCEEDED(hr)) {
    std::vector<IDispatchPtr> instances;
    hr = FindVisualStudioInstances(slnFile, instances);
    ReportHRESULT(hr, "FindVisualStudioInstances");

    if (SUCCEEDED(hr)) {
      count = static_cast<int>(instances.size());
    }

    // Force release all COM pointers before CoUninitialize:
    instances.clear();

    CoUninitialize();
  }
#else
  (void)slnFile;
#endif

  return count;
}

//! Get all running objects from the Windows running object table.
//! Save them in a map by their display names.
int cmCallVisualStudioMacro::CallMacro(const std::string& slnFile,
                                       const std::string& macro,
                                       const std::string& args,
                                       const bool logErrorsAsMessages)
{
  int err = 1; // no comdef.h

  LogErrorsAsMessages = logErrorsAsMessages;

#if defined(HAVE_COMDEF_H)
  err = 2; // error initializing

  HRESULT hr = CoInitialize(0);
  ReportHRESULT(hr, "CoInitialize");

  if (SUCCEEDED(hr)) {
    std::vector<IDispatchPtr> instances;
    hr = FindVisualStudioInstances(slnFile, instances);
    ReportHRESULT(hr, "FindVisualStudioInstances");

    if (SUCCEEDED(hr)) {
      err = 0; // no error

      std::vector<IDispatchPtr>::iterator it;
      for (it = instances.begin(); it != instances.end(); ++it) {
        hr = InstanceCallMacro(*it, macro, args);
        ReportHRESULT(hr, "InstanceCallMacro");

        if (FAILED(hr)) {
          err = 3; // error attempting to call the macro
        }
      }

      if (instances.empty()) {
        // no instances to call

        // cmSystemTools::Message(
        //  "cmCallVisualStudioMacro::CallMacro no instances found to call",
        //  "Warning");
      }
    }

    // Force release all COM pointers before CoUninitialize:
    instances.clear();

    CoUninitialize();
  }
#else
  (void)slnFile;
  (void)macro;
  (void)args;
  if (LogErrorsAsMessages) {
    cmSystemTools::Message("cmCallVisualStudioMacro::CallMacro is not "
                           "supported on this platform");
  }
#endif

  if (err && LogErrorsAsMessages) {
    std::ostringstream oss;
    oss << "cmCallVisualStudioMacro::CallMacro failed, err = " << err;
    cmSystemTools::Message(oss.str());
  }

  return 0;
}
