/* ====================================================================
 * Copyright (c) 2006-2007, Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// sc
#include "config.h"
#include "CrashHandler.h"
#include "version.out.h"
#include "Utility.h"

// qt
#include <QtCore/QString>

// sys
#ifdef _WIN32
#include <mapi.h>
#endif // _WIN32


// helper
static const char* copyString( const sc::String& src )
{
  QString s = QString::fromUtf8(src); 
  QByteArray qs = s.toLocal8Bit();
  char* result = (char*)calloc( qs.length()+1, 1 );
  strncpy( result, (const char*)qs, qs.length() );
  return result;
}

static sc::String getSubject()
{
  QString sbj = _q("%1 [%2] crashed...").arg(getLongAppName()).arg(SUBCOMMANDER_VERSION);
  return sc::String(sbj.toUtf8());
}

static sc::String getMessage()
{
  QString msg;
  msg +=
    _q("Please send the attached stack trace and crash dump to crash@subcommander.tigris.org.");
  msg += "\n\n";
  msg +=
    _q("<If you are able to reproduce the crash please describe how.>" );
  msg += "\n\n";
  msg +=
    _q("Thank you.");

  return sc::String(msg.toUtf8());
}


CrashHandler::CrashHandler()
{
}

void CrashHandler::handleException( const sc::String& stack, const sc::String& dump )
{
#if _WIN32
  typedef ULONG (FAR PASCAL *MAPISendMail)(
    LHANDLE lhSession,ULONG ulUIParam,lpMapiMessage lpMessage,FLAGS flFlags,ULONG ulReserved);

  HMODULE hMapi = LoadLibrary( "MAPI32.dll" );
  if( hMapi )
  {
    MAPISendMail MapiSendMail = (MAPISendMail)GetProcAddress( hMapi, "MAPISendMail" );
    if( MapiSendMail )
    {
      MapiFileDesc attachment[] =
      {
        { 
          0,                                             // reserved
          0,                                             // data file
          (ULONG)-1,                                     // position
          (LPSTR)copyString(stack),                      // full path
          NULL,                                          // display name
          NULL                                           // file details
        },
        { 
          0,                                             // reserved
          0,                                             // data file
          (ULONG)-1,                                     // position
          (LPSTR)copyString(dump),                       // full path
          NULL,                                          // display name
          NULL                                           // file details
        }
      };


      sc::String target(_s("crash@subcommander.tigris.org"));

      MapiRecipDesc recipient =
      {
        0,                                             // reserved
        MAPI_TO,                                       // recipient class
        NULL,                                          // name
        (LPSTR)copyString(target),                     // address
        0,                                             // entry id size
        NULL                                           // entry id
      };


      sc::String subject = getSubject();
      sc::String text    = getMessage();

      MapiMessage message =
      {
        0,                                             // reserved
        (LPSTR)copyString(subject),                    // subject
        (LPSTR)copyString(text),                       // message
        NULL,                                          // message type
        NULL,                                          // date
        NULL,                                          // conversation ID
        0L,                                            // flags
        NULL,                                          // originator
        1,                                             // recipient count
        &recipient,                                    // recipents
        2,                                             // attachment count
        &attachment[0]                                 // attachments
      };

      ULONG res = MapiSendMail( 0L, 0L, &message, MAPI_DIALOG, 0L );
    }

    FreeLibrary(hMapi);
  }
#endif // _WIN32
}
