/*==LICENSE==*

CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011  Cyan Worlds, Inc.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

You can contact Cyan Worlds, Inc. by email legal@cyan.com
 or by snail mail at:
      Cyan Worlds, Inc.
      14617 N Newport Hwy
      Mead, WA   99021

*==LICENSE==*/
/*****************************************************************************
*
*   $/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/Win32/pnCreMail.cpp
*   
***/

#include "../Pch.h"
#pragma hdrstop


//============================================================================
namespace Crash {
//============================================================================


/*****************************************************************************
*
*   Local functions
*
***/

//============================================================================
static bool CreateInheritablePipe (
    HANDLE *    read, 
    HANDLE *    write,
    bool        inheritRead
) {
    // create pipe for std error read/write
    if (!CreatePipe(read, write, (LPSECURITY_ATTRIBUTES) NULL, 0))
        return false;

    // make the appropriate handle inheritable
    HANDLE hProcess = GetCurrentProcess();
    HANDLE * inherit = inheritRead ? read : write;
    bool result = DuplicateHandle(
        hProcess,
        *inherit, 
        hProcess,
        inherit,
        0,
        true,   // make inheritable
        DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS
    );
    if (!result)
        return false;

    return true;
}


/*****************************************************************************
*
*   Module functions
*
***/

//============================================================================
void CrashSendEmail (
    const char smtp[],
    const char sender[],
    const char recipients[],
    const char replyTo[],
    const char username[],
    const char password[],
    const char programName[],
    const char errorType[],
    const char logBuffer[]
) {
    enum {
        IN_CHILD,
        IN_PARENT,
        NUM_PIPES
    };

    unsigned i;
    
    HANDLE pipes[NUM_PIPES];
    for (i = 0; i < arrsize(pipes); ++i)
        pipes[i] = INVALID_HANDLE_VALUE;


    for (;;) {
        // create pipes for Server -> StdIn -> Client
        if (!CreateInheritablePipe(&pipes[IN_CHILD], &pipes[IN_PARENT], true))
            break;
    
        char subject[512];
        StrPrintf(
            subject,
            arrsize(subject),
            "\"[Crash] %s, %s\"",
            programName,
            errorType
        );

        char cmdLine[512];
        StrPrintf(
            cmdLine,
            arrsize(cmdLine),
            "plMail.exe -smtp %s -sender %s",
            smtp,
            sender
        );
        
        if (replyTo && replyTo[0]) {
            StrPack(cmdLine, " -replyTo ", arrsize(cmdLine));
            StrPack(cmdLine, replyTo, arrsize(cmdLine));
        }
        
        if (username && username[0]) {
            StrPack(cmdLine, " -u ", arrsize(cmdLine));
            StrPack(cmdLine, username, arrsize(cmdLine));
        }

        if (password && password[0]) {
            StrPack(cmdLine, " -p ", arrsize(cmdLine));
            StrPack(cmdLine, password, arrsize(cmdLine));
        }
        
        StrPack(cmdLine, " ", arrsize(cmdLine));
        StrPack(cmdLine, recipients, arrsize(cmdLine));

        StrPack(cmdLine, " ", arrsize(cmdLine));
        StrPack(cmdLine, subject, arrsize(cmdLine));

        // create process
        STARTUPINFO si;
        ZERO(si);
        si.cb           = sizeof(si);
        si.dwFlags      = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        si.wShowWindow  = SW_HIDE;
        si.hStdInput    = pipes[IN_CHILD];
        si.hStdOutput   = INVALID_HANDLE_VALUE;
        si.hStdError    = INVALID_HANDLE_VALUE;
        PROCESS_INFORMATION pi;
        BOOL result = CreateProcess(
            NULL,
            cmdLine,
            (LPSECURITY_ATTRIBUTES) NULL,
            (LPSECURITY_ATTRIBUTES) NULL,
            true,      // => inherit handles
            NORMAL_PRIORITY_CLASS,
            NULL,
            NULL,
            &si,
            &pi
        );
        if (!result)
            break;
            
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);

        // Write output data
        DWORD written, length = StrLen(logBuffer);
        WriteFile(pipes[IN_PARENT], logBuffer, length, &written, NULL);

        // complete
        break;
    }

    // cleanup pipes
    for (i = 0; i < arrsize(pipes); ++i) {
        if (pipes[i] != INVALID_HANDLE_VALUE)
            CloseHandle(pipes[i]);
    }
}



//============================================================================
} // namespace Crash
//============================================================================