#!/usr/bin/perl
use strict;
use warnings;
print <<'tag';

#########################################
# UNL ver. 0.1				#
# Unlisted Number Lister		#
# Lists numbers not found in		#
# Superpages.com's directory		#
# for a given NPA-NXX			#
#					#
# rEph					#
# (robf [at] flamegrilled [dot] net)	#
#########################################

tag

# Globals

my %number;
my $BusNum = 0;
my $ResNum = 0;

## Modules

use Time::Duration;
use HTTP::Request::Common;
require LWP::UserAgent;
my $UserAgent = LWP::UserAgent->new;
$UserAgent->agent("Mozilla/5.0");

## Main

my $NPA = checkinput('NPA');
my $NXX = checkinput('NXX');
my $filename = $NPA.".".$NXX.".XXXX.txt";
print "\nOutputting $NPA-$NXX-XXXX's unlisted numbers to $filename\nPlease be patient, this may take a while.\n\n";
print "Scanning Residential Directory\n"."-" x 30 . "\n";
my $start_time = time();

# Residential Search

for (my $suffix = 0; $suffix < 10; $suffix++) {  
	results($suffix, 1);
}
print "\nScanning Business Directory\n"."-" x 27 . "\n";

# Business Search
for (my $suffix = 0; $suffix < 100; $suffix++) { 
	results($suffix, 2);
}
print "\nWriting unlisted numbers to file\n" . "-" x 32 . "\n";
sifter();

### Error Checking
sub checkinput {
	my $temp = shift;
	while (1){
		print "Enter the $temp.\n";
		chomp($_ = <STDIN>);
		if ($_=~/^\d{3,3}?$/) {
			return $_;
		}
		print "$temp must be 3 digits.\n\n";
	}	
}

## Parsing Results

sub results {
	my $CurrentCount = 0;
	my $URI;
	my $suffix = shift;
	my $type = shift;
	if ($type == 1) {print "Scanning $NPA-$NXX-$suffix"."xxx";} 
	elsif ($type == 2) {
		$suffix = sprintf("%02d", $suffix);
		print "Scanning $NPA-$NXX-$suffix"."xx";}
	my $FollowPage = 1;
	my $PI = 1;
	while ($FollowPage) {
		if ($type == 1) {
			$URI = "http://directory.superpages.com/wp/results.jsp?SRC=&STYPE=WR&PS=60&PI=$PI&A=$NPA&X=$NXX&P=$suffix***&search=Find";
		} elsif ($type == 2) {
			$URI = "http://yellowpages.superpages.com/listings.jsp?SRC=&PS=45&A=$NPA&X=$NXX&P=$suffix**&PP=N&STYPE=AP&paging=1&PI=$PI";
		}
		$FollowPage = 0;
		my $response  = $UserAgent->request(GET "$URI");
		my $content = $response->content;
		if ($type == 1) {
			if ($FollowPage == 0 && $content=~m/Next Page/) { $FollowPage++; $PI++ }
			while ($content=~m/\($NPA\) $NXX - (\d{4,4}?)/go) {  unless ($number{$1}) {$ResNum++; $CurrentCount++;} $number{$1} = 1;}
		} elsif ($type == 2) {
			if ($FollowPage == 0 && $content=~m/>Next/) { $FollowPage++; $PI += 45}
			while ($content=~m/\($NPA\) $NXX-(\d{4,4}?)/go) {  unless ($number{$1}) {$BusNum++; $CurrentCount++;} $number{$1} = 1; }
		}
	}
	print " - $CurrentCount numbers found\n";
}

### Checks Keys against each possible suffix and outputs nonexisting suffixes
sub sifter {
	my $count = 0;
	my $sift;
	open (OUTPUT, ">>$filename") or die 'Failed to open output file!!\n';
	for ($sift = 0; $sift < 10000; $sift++) {
		$sift = sprintf("%04d", $sift);
		unless ($number{$sift}) {
			$count++;
			print OUTPUT "$NPA.$NXX.$sift\n";
		}
	}
	close OUTPUT;
	print "\nStatistics\n" . "-" x 10 . "\n";
	print "$ResNum\tUnique listed Residential numbers found.\n";
	print "$BusNum\tUnique listed Business numbers found.\n";
	print "$count\tUnlisted numbers found.\n\n";
	printf "%.0f%%\tUnlisted\n%.0f%%\tResidential\n%.0f%%\tBusiness\n", $count/10000*100, $ResNum/10000*100, $BusNum/10000*100;
}
print "\nScan was completed in " .  duration(time() - $start_time) . ".\n";
exit(0);