#!/usr/bin/perl

use HTTP::Request::Common;
use LWP::UserAgent;


package Pagersite;

sub new {
	my $class=shift;
	
	my $obj={
		aliases	=> [],
		url	=> "",
		comment	=> "",
		method	=> "POST",
		pager	=> "",
		message	=> ""
	};

	bless $obj,$class;
	return $obj;
}

sub addalias {
	my ($self,$alias)=@_;

	push(@{$self->{aliases}},$alias);
}

sub check_alias {
	my ($self,$alias)=@_;

	for (@{$self->{aliases}}) {
		return 1 if ($alias eq $_);
	}
	return 0;
}

sub dump {
	my ($self)=@_;
	my $a;

	print("[ " . $self->{aliases}->[0] . " ]\n");
	for (@{$self->{aliases}}) {
		print("	alias=$_\n");
	}
	print("	comment=$self->{comment}\n");
	print("	url=$self->{url}\n");
	print("	method=$self->{method}\n");
	print("	pager=$self->{pager}\n");
	print("	message=$self->{message}\n");
}



package main;

my $CONF="/etc/bip.conf";	# Configuration file
my @psps;
my $current;
my %target;
my $message;

sub usage {
	print STDERR "Send message to pagers using the Internet
Usage:	bip <operator> <pgids> \<message>\
	bip -p <operator> <pgids> [-p <operator> <pgids> ...] \<message>\
	bip -l

Where:
    -p          Use the <operator> Pager Service Provider name or alias to
                send the message
    -l          Lists all Pager Service Provider names, aliases and comments
                defined in /etc/bip.conf
    operator    The name or alias of a Pager Service Provider as defined
                in /etc/bip.conf
    pgids       A list of pager IDs to send the message
    message     The message text surrounded by \\ or \"\". If message is
                the \-\ char, reads message text from standard input

Examples:
    bip teletrim 12345 73482 \Hello World\
    bip -p conectel 16423 883545 -p trim 112643 237433 \Hello Again\
    echo \Call office\ | bip trim 634243 -
    df -k | bip powernet 234679 -
";
}


sub get_psp_from_alias {
	my ($alias)=@_;
	my $pg;

	foreach $pg (@psps) {
		return $pg if $pg->check_alias($alias);
	}
	return 0;
}

sub list {
	my $psp;
	my $comment;
	my $c;

	for $psp (@psps) {
		print $psp->{aliases}->[0];
		for ($c=1;$c<=$#{$psp->{aliases}};$c++) {
			print ", $psp->{aliases}->[$c]";
		}
		print "\n";
		$comment=$psp->{comment};
		$comment=~s/^/	/mg;
		print $comment;
	}
}

sub read_config {
	my $current;
	open(CF,$CONF) || die "Sem config"; 
	while (<CF>) {
		my $alias,$url,$comment,$method,$pager,$message;
		chop;
		s/\#.*//;		# remove coments
		next if (/^\s*$/);	# ignore blank lines
		SWITCH: {
			if (/\[\s*(\S.*\S)\s*\]/) {
				$current=new Pagersite;

				$alias=$1;
		
				push(@psps,$current);
				$current->addalias($alias);
				last SWITCH;
			}
			if (/alias\s*=\s*(\S.*\S)\s*/) {
				$alias=$1;
				$current->addalias($alias);
				last SWITCH;
			}
			if (/comment\s*=\s*(.*)/) {
				$comment=$1;
				$current->{comment}.="$comment\n";
				last SWITCH;
			}
			if (/url\s*=\s*(\S.*\S)\s*/) {
				$url=$1;
				$current->{url}=$url;
				last SWITCH;
			}
			if (/method\s*=\s*(\S.*\S)\s*/) {
				$method=$1;
				$current->{method}=$method;
				last SWITCH;
			}
			if (/pager\s*=\s*(\S.*\S)\s*/) {
				$pager=$1;
				$current->{pager}=$pager;
				last SWITCH;
			}
			if (/message\s*=\s*(\S.*\S)\s*/) {
				$message=$1;
				$current->{message}=$message;
				last SWITCH;
			}
		}
	}
}

sub read_cmdline {
	my $cpsp;
	while ($#ARGV>=0) {
		$_=shift(@ARGV);
		SWITCH: {
	#		if ($_ eq "-w") {
	#			$WAIT=shift(@ARGV);
	#			last SWITCH;
	#		}
			if ($_ eq "-h" || $_ eq "--help") {
				usage();
				exit 0;
			}
			if ($_ eq "-m") {
				$message=shift(@ARGV);
				last SWITCH;
			}
			if ($_ eq "-l") {
				$LIST=true;
				last SWITCH;
			}
			if ($_ eq "-p") {
				$cpsp=shift(@ARGV);
				if (! exists($target{$cpsp})) {
					$target{$cpsp}->[0]=get_psp_from_alias($cpsp);
					$target{$cpsp}->[1]=[];
				}
				while ($#ARGV>=0) {
					my $arg=shift(@ARGV);

					if ($#ARGV==-1) {
						$message=$arg;
						last SWITCH;
					}
					if ($arg=~/^\-/) {
						unshift(@ARGV,$arg);
						last SWITCH;
					}
					push(@{$target{$cpsp}->[1]},$arg);
				}
				last SWITCH;
			}
			$cpsp=$_;
			$target{$cpsp}->[0]=get_psp_from_alias($cpsp);
			$target{$cpsp}->[1]=[];
			while ($#ARGV>0) {
				push(@{$target{$cpsp}->[1]},shift(@ARGV));
			}
			$message=shift(@ARGV);
		}
	}
}

sub check_config {
	my $t;
	for $t (keys(%target)) {
		if ($target{$t}->[0]==0) {
			print STDERR "Cant find configuration for $t. Ignoring.\n";
			delete($target{$t});
		}
	}
	if ($message=~/^-$/) {
		$message="";
		while (<STDIN>) {
			$message.=$_;
		}
	}
}


sub sendm {
	my $ua=LWP::UserAgent->new;
	my $cpsp,$i;
	my $req,$id;
	
	for $i (keys(%target)) {
		$cpsp=$target{$i}->[0];
		for $id (@{$target{$i}->[1]}) {
			if ($cpsp->{method}=~/get/i) {
				$req=GET($cpsp->{url},[$cpsp->{pager} => $id, $cpsp->{message} => $message]);
			} elsif ($cpsp->{method}=~/post/i) {
				$req=POST($cpsp->{url},[$cpsp->{pager} => $id, $cpsp->{message} => $message]);
			}
			$ua->request($req);
		}
	}
}

read_config;
read_cmdline;


if ($LIST eq "true") {
	list;
	exit 0;
}


check_config;
sendm;

# for $psp (keys(%target)) {
# 	print("[ $target{$psp}->[0]->{aliases}->[0] ]\n");
# 	print("	url=$target{$psp}->[0]->{url}\n");
# 	print("	ids=");
# 	for (@{$target{$psp}->[1]}) {
# 		print("$_ ");
# 	}
# 	print("\n");
# }
#
# print("\nmessage=$message\n");
