#!/usr/bin/perl -w

use strict;
use HTML::Form;
use HTML::Entities;
use HTTP::Request;
use LWP;
use Getopt::Long;
use Data::Dumper;

my $username;
my $password;
my $contacts = 0;
my $message;
my @recipients = ();
my $DELAY = 1;

if ($^O eq "darwin") {
	# Log in once to webtext under safari and this will work
	# you need to allow the security program to access the keychain
	open(IN, "security find-internet-password -g -s www.vodafone.ie -r htps 2>&1 |") || die "$!";
	while(<IN>) {
		if (m/"acct"<blob>="(.*)"/) { $username = $1; }
		if (m/password: "(.*)"/) { $password = $1; }
	}
	close(IN);
} else {
	my $rcfile=$ENV{HOME} . "/.webtextrc";
	if (-f $rcfile) {
		if (open(IN, "<$rcfile")) {
			while(<IN>) {
				chomp;
				if (m/username=(.*)/) { $username = $1; }
				if (m/password=(.*)/) { $password = $1; }
			}
			close(IN);
		}
	}
}

# use something else, or program the passwords here
$username="username" if (!defined($username));
$password="password" if (!defined($password));

die "Please configure the username and password" if ($username eq "username");

my $webtext_url="https://www.vodafone.ie/myv/messaging/webtext/index.jsp";

sub usage {
	print "$0 [-c] [-t <addressee1> [-t ...<addressee5>] Message]\n";
	exit 0
}

my $result = GetOptions("to|t=s" => \@recipients, "contacts|c" => \$contacts);

usage() if ($contacts == 0) && ((scalar(@recipients) == 0) || (scalar(@recipients) > 5) ||
  (scalar(@ARGV) == 0));

$message = join(" ", @ARGV);

if (length($message) > 160) {
	die "Message too long.\n Shorten to: \"" . substr($message, 0, 160) . "\"";
}

my $ua = LWP::UserAgent->new;
push @{ $ua->requests_redirectable }, 'POST';
$ua->cookie_jar({ });
$ua->agent('Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/523.10.3 (KHTML, like Gecko) Version/3.0.4 Safari/523.10');
my $response = $ua->get($webtext_url);
#print Dumper($response);
my @forms = HTML::Form->parse($response->content, $response->base);
my $form = undef;
foreach (@forms) {
	if (defined($_->{'attr'}) &&
		lc($_->{'attr'}{'name'}) eq "login") {
		$form=$_;
	}
}
die "Could not get Login Form" unless $form;
$form->value('username', $username);
$form->value('password', $password);
$response = $ua->request($form->click);
die "Login Failed" if (!$response->is_success || $response->base =~ /Login.shtml/);
$response->as_string() =~ /emaining messages this month.*>(\d+)</s
    or die "Unexpected response: " . $response->as_string() . "  Couldn't determine number of remaining texts";
my $remaining = $1;

#print Dumper($response);

@forms = HTML::Form->parse($response->content, $response->base);
$form = undef;
foreach (@forms) {
	if (defined($_->{'attr'}) &&
		lc($_->{'attr'}{'name'}) eq "webtext") {
		$form=$_;
	}
}
die "Could not get Webtext Form" unless $form;

sub trim($)
{
	my $string = shift;
	$string =~ s/^\s+//;
	$string =~ s/\s+$//;
	return $string;
}

# walk the label for=... -> form id=... matches
my %chk_labels;
my %address_book;
my %lc_address_book;
%chk_labels = $response->content =~ m/label for="chk_box_(\d*)">([^<]*)</g;
#print Dumper($form);
foreach (keys(%chk_labels)) {
	my $iv = $form->find_input("chk_box_$_");
	my $name = trim(decode_entities($chk_labels{$_}));
	$address_book{$name} = $iv->{menu}[1]{'value'};
	$lc_address_book{lc($name)} = $iv->{menu}[1]{'value'};
}

if ($contacts == 1) {
    foreach(sort(keys(%address_book))) {
        print "$_ on " . $address_book{$_} . "\n";
    }
    exit (0);
}

$form->value('message', $message);
my $i = 0;
print "Sending: $message to ";
foreach (@recipients) {
	my $phone = $_;
	if (!($phone =~ /^[0-9]/)) {
		$phone = $lc_address_book{lc($phone)};
	}
	$form->value("recipients[$i]", $phone);
	print $phone . " ";
	$i++;
}
print "\n";
sleep($DELAY);
$response = $ua->request($form->click);
die "Message was not sent correctly" . Dumper($response) if (!($response->as_string() =~ /Your message was sent to:/));
$response = $ua->get($webtext_url);
$response->as_string() =~ /emaining messages this month.*>(\d+)</s
    or die "Unexpected response: " . $response->as_string() . "  Couldn't determine number of remaining texts";
if ($remaining == $1) {
	die "Even though the message was sent, the number of available messages didn't reduce";
}
print "Remaining Messages: $1\n";
exit 0
