#!/usr/local/bin/perl -w
use strict;
#---------------------------------------------------------------------#
# This source code is (c)1998 Dave Belfer-Shevett - shevett@pobox.com #
# see http://www.stonekeep.com/license.html for licensing information #
#---------------------------------------------------------------------#

#----------------------------------------------------------------------
# keymail.pl
# $Id: keymail.pl,v 1.38 2000/12/28 18:20:12 nclemons Exp $
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#
# This is keymail, the email front end for use with the Keystone 
# IT management system.  Keystone must be installed and configured
# in order to use this.
#
#----------------------------------------------------------------------

#---------------------------------------------------------------------------
# define stuff

#---------------------------------------------------------------------------
use Getopt::Long;
use FindBin;
use Mail::Internet;
use Mail::Address;
unshift @INC, "$FindBin::RealBin";

# Use require so it will be loaded after the unshift command above.
#
require Keystone;

#---------------------------------------------------------------------------

my %options;

# So we don't have an uninitialized variable warning.
#
$options{debug} = 0;

GetOptions(\%options, "h", "help", "slip=i", "status=s", "brief", "newslip",
    "mailinfo", "parent=i", "mailreply", "currtech=s", "priority=i", "noreply",
    "debug", "children", "followups", "newfollowup", "showslip", "public");

my $key = new Keystone ( 'debug' => $options{debug} );

#---------------------------------------------------------------------------
# Broker out what folks wanna do.

if ($options{help} || $options{h}) {
    print $key->help(%options);
    undef $key;
    exit;
}

if ($options{showslip}) {
    showslip(%options);
    undef $key;
    exit;
}

if ($options{newfollowup}) {
    newfollowup(%options);
    undef $key;
    exit;
}

if ($options{newslip}) {
    addslip(%options);
    undef $key;
    exit;
}

if ($options{mailinfo}) {
    $key->mailinfo(%options);
    undef $key;
    exit;
}

sub addslip {
    my %param = @_;

    my $mail = Mail::Internet->new([<>]) || die ("Failed: $!\n");
    if ($key->config_var("m_removesignature")) {
       $mail->remove_sig;
    }
    $mail->tidy_body;

    my $rply = $mail->reply || die ("Failed: $!\n");
    my $header = $mail->head;
    my $replhead = $rply->head;
    $replhead->replace('From:',"From: " . $key->config_var("f_from") );
    my $sline = $header->get('Subject') || "";
    chomp $sline;

    my $fline;

    if ($header->get('X-Sender')) {
        $fline = $header->get('X-Sender') || "";
        chomp $fline;
    } else {
        $fline = $header->get('From') || "";
        chomp $fline;
    }

    my $body;
 
    if ($key->config_var("m_removeheader") == 2) {
        $body = "From: $fline\n\n" . join('',@{$mail->body});
    } elsif ($key->config_var("m_removeheader") == 1) {
        $body = join('',@{$mail->body});
    } else {
        $body = $mail->as_string;
    }
    my $body_plain = $body;
    $body=quotemeta($body);

    # pull just the actual email address out of the fline
    #my ($pfline) = Mail::Address->parse($fline) || die ("Failed: $!\n");
    #my $opentech = $pfline->address;
    #
    (my @addrs = Mail::Address->parse($fline)) || die ("Failed to parse mail address!\n");
    my $opentech;
    my $addr;
    foreach $addr (@addrs) {
	$opentech .= $addr->address;
	$opentech .= ",";
    }
    $opentech = substr($opentech, 0, length($opentech) - 1);

    # Stuff here

    my $insertid = $key->addslip(%param, 'fline', $fline,
	'sline', $sline, 'body', $body, "opentech", $opentech);
   
    my $nline = $sline;
    $nline =~ s/^/[Slip: #$insertid] /;
    $replhead->replace('Subject:',"Subject: $nline");


    $param{noreply} && return;

    my $nstring = localtime(time());

    my $safe = new Safe;

    my $tmpl_filename;

    if (-e "$FindBin::RealBin/templates/addslip.tmpl") {
	$tmpl_filename = "$FindBin::RealBin/templates/addslip.tmpl";
    } else {
	$tmpl_filename = "$FindBin::RealBin/templates/addslip.tmpl.default";
    }

    my $retval = Text::Template::fill_in_file(
	$tmpl_filename,
	SAFE => $safe,
	HASH => { "sys_website" => $key->config_var("website"),
	    "body" => $body_plain, "sys_url" => $key->config_var("url"),
	    "insertid" => $insertid, "nstring" => $nstring,
	    "fline" => $fline, "sline" => $sline }
	);

    push @{$rply->body}, "$retval\n";

    my $to = $replhead->get("To");

    $rply->smtpsend( To => $to, Cc => $key->config_var("ccmail"),
	Host => $key->config_var("smtpserver") );
}

sub showslip {
    my %param = @_;

    my $mail = Mail::Internet->new([<>]) || die ("Failed: $!\n");
    if ($key->config_var("m_removesignature")) {
       $mail->remove_sig;
    }
    $mail->tidy_body;

    my $rply = $mail->reply || die ("Failed: $!\n");
    my $header = $mail->head;
    my $replhead = $rply->head;
    my $m_from = $key->config_var("m_from");
    $replhead->replace('From:',"From: $m_from");

    my $sline = $header->get('Subject') || "";
    chomp $sline;

    # Let's pull the slip from the Subject: if it wasn't provided via
    # --slip.
    #
    if (!$param{slip}) {
	($param{slip}) = ($sline =~ m/#(\d+)/g);
	$param{slip} ||= "";
    }

    # TODO: See if we have a slip number at all.
    #
    if ($param{slip} !~ m/^\d+$/) {
	my $body = $mail->as_string;

	push @{$rply->body},
	    "I'm sorry, but I could not determine the slip ID # from your\n";
	push @{$rply->body},
	    "Subject: line. The correct format to view a slip is:\n";
	push @{$rply->body}, "\n";
	push @{$rply->body},
	    "Subject: #(number)\n";
	push @{$rply->body}, "\n";
	push @{$rply->body},
	    "Where you type the number sign, then the slip ID number.\n";

	$rply->smtpsend(Host=> $key->config_var("smtpserver"));
	return;
    }

    # TODO: Verify the slip is valid before processing.
    #
    my $retval = $key->showslip(%param);

    # Actually, reply() is nice to set the headers and so on, but
    # no need to quote the email in our reply...
    #
    @{$rply->body} = ();

    push @{$rply->body}, "\n$retval";

    my $to = $replhead->get("To");

    $rply->smtpsend( To => $to, Host => $key->config_var("smtpserver") );
}

sub newfollowup {
    my %param = @_;

    my $mail = Mail::Internet->new([<>]) || die ("Failed: $!\n");
    if ($key->config_var("m_removesignature")) {
       $mail->remove_sig;
    }
    $mail->tidy_body;

    my $rply = $mail->reply || die ("Failed: $!\n");
    my $header = $mail->head;
    my $replhead = $rply->head;
    my $f_from = $key->config_var("f_from");
    $replhead->replace('From:',"From: $f_from");

    my $sline = $header->get('Subject') || "";
    chomp $sline;

    # Let's pull the slip from the Subject: if it wasn't provided via
    # --slip.
    #
    if (!$param{slip}) {
	($param{slip}) = ($sline =~ m/#(\d+)/g);
    }

    # TODO: See if we have a slip number at all.
    #
    if ($param{slip} !~ m/^\d+$/) {
	my $body = $mail->as_string;

	push @{$rply->body},
	    "I'm sorry, but I could not determine the slip ID # from your\n";
	push @{$rply->body},
	    "Subject: line. The correct format to add a followup is:\n";
	push @{$rply->body}, "\n";
	push @{$rply->body},
	    "Subject: #(number)\n";
	push @{$rply->body}, "\n";
	push @{$rply->body},
	    "Where you type the number sign, then the slip ID number.\n";

	$rply->smtpsend(Host=> $key->config_var("smtpserver"));
	return;
    }

    my $fline;

    if ($header->get('X-Sender')) {
        $fline = $header->get('X-Sender') || "";
        chomp $fline;
    } else {
        $fline = $header->get('From') || "";
        chomp $fline;
    }

    # TODO: Verify the slip is valid before processing.
    #

    # my $body = $mail->as_string;
    my $body ;
    if ($key->config_var("m_removeheader") == 2) {
        $body = "From: $fline\n\n" . join('',@{$mail->body});
    } elsif ($key->config_var("m_removeheader") == 1) {
        $body = join('',@{$mail->body});
    } else {
        $body = $mail->as_string;
    }

    $key->addfollowup(%param, 'f_text', $body);

    $param{noreply} && return;

    my $safe = new Safe;

    my $tmpl_filename;

    if (-e "$FindBin::RealBin/templates/addfollowup.tmpl") {
	$tmpl_filename = "$FindBin::RealBin/templates/addfollowup.tmpl";
    } else {
	$tmpl_filename = "$FindBin::RealBin/templates/addfollowup.tmpl.default";
    }

    my $retval = Text::Template::fill_in_file(
	$tmpl_filename,
	HASH => { "slipid" => $param{slip}, "f_text" => $body,
	    "sys_url" => $key->config_var("url"),
	    "sys_website" => $key->config_var("website") },
	SAFE => $safe);

    push @{$rply->body}, "$retval\n";

    my $to = $replhead->get("To");

    $rply->smtpsend( To => $to, Cc => $key->config_var("notify"),
	Host => $key->config_var("smtpserver") );
}

