/*============================================================================
  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.
//
#if ( _MSC_VER >= 1300 )
// VS7 and later:
#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
#else
// VS6 only had comsupp.lib:
# pragma comment(lib, "comsupp.lib")
#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 oss; \
      oss.flags(std::ios::hex); \
      oss << context << " failed HRESULT, hr = 0x" << hr << std::endl; \
      oss.flags(std::ios::dec); \
      oss << __FILE__ << "(" << __LINE__ << ")"; \
      cmSystemTools::Message(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(0 == instances.size())
        {
        // 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;
}
