/**
 *  A program that takes as input two files, a mail template and a csv file with a list of people to
 *  send a mail to.  The csv file is formatted:
 *
 *      companyname,jobtitle,firstname,lastname,phonenumber,emailaddress
 *
 *  and the mail template can use markers such as <%= firstname %> which will get edited with information from
 *  the current person being mailshotted.  Basically this is a standard mail merge type thing but it actually
 *  send email rather than creates postal letters.
 *
 *  @author Russel Winder
 *  @version 0.1.1
 *  @date 2007-02-08
 *  @copyright Copyright © 2004-7 Russel Winder.  All rights reserved.
 */

#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <vector>

#include <bits/stl_pair.h>

std::string emailSubjectLine ;
std::string emailTemplate ;

std::pair<std::string, std::string> transform ( const std::string & toData ) {
  int frontIndex = 0 ;
  int backIndex = 0 ;
  std::vector<std::string> definitions ;
  while ( ( frontIndex = toData.find ( ',' , backIndex ) ) != toData.npos ) {
    if ( index > 0 ) { definitions.push_back ( toData.substr ( backIndex , frontIndex - backIndex ) ) ; }
    backIndex = frontIndex + 1 ;
  }
  definitions.push_back ( toData.substr ( backIndex ) ) ;
  std::string message ( emailTemplate ) ;
  std::vector<std::string> editStrings ;
  editStrings.push_back ( "<%= companyname %>" ) ;
  editStrings.push_back ( "<%= jobtitle %>" ) ;
  editStrings.push_back ( "<%= firstname %>" ) ;
  editStrings.push_back ( "<%= lastname %>" ) ;
  editStrings.push_back ( "<%= phonenumber %>" ) ;
  editStrings.push_back ( "<%= emailaddress %>" ) ;
  for ( int i = 0 ; i <= 5 ; ++i ) {
    int index = 0 ;
    while ( ( index = message.find ( editStrings[i] ) ) != message.npos ) {
      message.erase ( index , editStrings[i].size ( ) ) ;
      message.insert ( index , definitions[i] ) ;
    }
  }
  return std::pair<std::string, std::string> ( definitions[5] , message ) ;
}

void process ( const std::string & toData ) {
  const std::pair<std::string, std::string> data = transform ( toData ) ;
  system ( ( "sh -c  \"mail -s \\\"" + emailSubjectLine + "\\\" " + data.first + " << XXXX\n" + data.second + "\"").c_str ( ) ) ;
}

int main ( const int ac , const char *const *const av ) {
  if ( ac != 4 ) {
    std::cout << "Usage: mailshot_mail <mail-subject-line> <mail-template> <targets-csv-file>" << std::endl ;
    return 1 ;
  }
  emailSubjectLine = av[1] ;
  const int bufferSize = 8192 ;
  char buffer [ bufferSize ] ;
  std::ifstream input ( av[2] ) ;
  int position = 0 ;
  while ( input ) {
    const char c = input.get ( ) ;
    buffer [ position++ ] = input.eof ( ) ? '\0' : c ;
  }
  emailTemplate = std::string ( buffer ) ;
  input.close ( ) ;
  input.open ( av[3] ) ;
  while ( input ) {
    input.getline ( buffer , bufferSize ) ;
    if ( ! input.eof ( ) ) { process ( std::string ( buffer ) ) ; }
  } 
  return 0 ;
}
