package LIMS::Local::Mail;

use Exporter;

@ISA = ('Exporter');

@EXPORT_OK = ('dispatch');

use strict;

use Data::Dumper;
use Email::Stuff;
use Mail::Sendmail;

#-------------------------------------------------------------------------------
# returns only on send failure:
sub dispatch {
    my $mail = shift; # warn Dumper $mail;

	# require 'to', 'from' & 'smtp' or return:
	return 'missing one or more mail elements (to, from, smtp)'
		if grep { ! $mail->{$_} } qw(to from smtp);

	# make sure we're in production mode, otherwise set 'to' address to safe:
	_verify_service_status($mail);
	
	return $^O =~ /MSWin32/
		? _win32($mail)		# uses Mail::Outlook
		: _sendmail($mail); # uses Mail::Sendmail
}

#-------------------------------------------------------------------------------
# return hashref containing keys 'success' (1 or 0) & 'message':
sub send_attachment {
    my $mail = shift;

	# require 'to', 'from', 'smtp', 'file' & 'filename' or return:
	return { # caller expects hashref containing key 'message' on failure:
		message => 'missing one or more mail elements (to, from, smtp, file, filename)'
	} if grep { ! $mail->{$_} } qw(to from smtp file filename);

	# make sure we're in production mode, otherwise set 'to' address to safe:
	_verify_service_status($mail);

    # set defaults:
    $mail->{subject} ||= '[no subject]';
    $mail->{message} ||= 'Attached file:';

	# need error return from this:
    my $result = Email::Stuff
        ->to($mail->{to})
        ->from($mail->{from})
        ->subject($mail->{subject})
        ->text_body($mail->{message})
		# or use 'attach_file' for filesystem file:
        ->attach($mail->{file}, filename => $mail->{filename}) 
		->using('SMTP', Host => $mail->{smtp})
        ->send; # warn 'Email::Stuff says:'  . $result;

	# Email::Stuff returns 'Message sent' if ok:
	return {
		success => ( $result eq 'Message sent' ),
		message => $result,
	}
}

#-------------------------------------------------------------------------------
sub _sendmail { 
	my $mail = shift; # warn Dumper $mail; return 0;

	# doesn't generate $@ so use M::S::error() instead
	eval { Mail::Sendmail::sendmail(%$mail) };
	
	return $Mail::Sendmail::error || 0;  # empty if mail sent OK
}

#-------------------------------------------------------------------------------
sub _win32 {
	my $data = shift; # warn Dumper $data; return 0;
	
    require Mail::Outlook;

    my %mail = (
        To      => $data->{to},
        Body    => $data->{message},
        Subject => $data->{subject},
    );

    my $o = new Mail::Outlook('Outbox');
    my $msg = $o->create(%mail);
    $msg->send(%mail);
	
	return 0; # need error rtn from Mail::Outlook
}

#-------------------------------------------------------------------------------
sub _verify_service_status {
	my $mail = shift;

	# check we're in production mode, return if so:
	return if $mail->{_app_cfg}->{is_in_production_mode};
	
	# set mail 'to' address to service 'safe' address:
	$mail->{to} = $mail->{_app_cfg}->{email_from}
	|| die "no 'email_from' address configured in config settings file";
	# delete any cc & bcc addresses:
	$mail->{cc} = $mail->{bcc} = undef;
}

1;