/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#include "cmCallVisualStudioMacro.h"
#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().c_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;
    OLECHAR *name = L"ExecuteCommand";

    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.c_str() << std::endl;
      oss << "  Args: " << args.c_str() << 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: " << 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;
    OLECHAR *name = L"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;
    OLECHAR *name = L"FullName";

    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().c_str());
    }

  return 0;
}
