#!/usr/bin/perl -w
#
# __copy1__
# __copy2__
#
use strict qw(vars);

# set $Cmd var
#
my $Cmd = $0; if ($Cmd =~ /\//) { $Cmd =~ s/\/[^\/]+$//; } else { $Cmd = `pwd`; }
unshift( @INC, $Cmd );
$Cmd	= $0; $Cmd =~ s/.*\///;

my @lookfiles = qw(
	telefono.csv
	telefono.txt
	tel.csv
	tel.txt
	google.csv
);

my $trush;
my @searchpath;
my @rebuildpath;
my $localcache;
my @OUT;
my @F;
my $VERBOSE = 0;
my $DEBUG = 0;
my $DFLAG = "";
my $extrainfo = 0;
my $do_rebuild = 0;
my $do_all = 0;
my @args;

# early option scan, detect debug option
#
while (@ARGV) {
	$_ = shift(@ARGV);
	if ($_ eq '-D' || $_ eq '--debug') {
		$DEBUG = 1;
		$DFLAG = "--debug";
	} else {
		push( @args, $_ );
	}
}
@ARGV = @args;


# set defaults from config files (jtconf)
#
$trush	= `jtconf $DFLAG $Cmd.searchpath 2>/dev/null`; chomp($trush);
if ($trush ne "") {
	@searchpath	= split( /:/, $trush );
	dprintf( "searchpath defined: >>%s<<\n", $trush );
} else {
	@searchpath	= ( "$ENV{HOME}/Documenti" );
	dprintf( "searchpath undefined, default: >>%s<<\n", join( ':', @searchpath ) );
}

$trush	= `jtconf $DFLAG $Cmd.rebuildpath 2>/dev/null`; chomp($trush);
if ($trush ne "") {
	@rebuildpath	= split( /:/, $trush );
	dprintf( "rebuildpath defined: >>%s<<\n", $trush );
} else {
	@rebuildpath	= ( "/w/prj", "/usr/prj" );
	dprintf( "rebuildpath undefined, default: >>%s<<\n", join( ':', @rebuildpath ) );
}

$trush	= `jtconf $DFLAG $Cmd.localcache 2>/dev/null`; chomp($trush);
if ($trush ne "") {
	$localcache	= $trush;
	dprintf( "localcache defined: >>%s<<\n", $trush );
} else {
	$localcache	= "$ENV{HOME}/.${Cmd}.cache";
	dprintf( "localcache undefined, default: >>%s<<\n", $localcache );
}



while (@ARGV) {
  my $arg = shift(@ARGV);
  CASE: {
	if ($arg eq "-v")			{ $VERBOSE = 1; last CASE; }
	if ($arg eq "-l" || $arg eq "--long")	{ $extrainfo = 1; last CASE; }
	if ($arg eq "-a" || $arg eq "--all")	{ $do_all = 1; last CASE; }
	if ($arg eq "--rebuild")		{ $do_rebuild = 1; last CASE; }
	if ($arg eq "--cachefile")		{ usage() if (!@ARGV);
					  	  $localcache = $ARGV[0];
					  	  shift(@ARGV);
					  	  last CASE; }
	if ($arg eq "--add")			{ usage() if (!@ARGV);
					  	  push( @rebuildpath, $ARGV[0] );
					  	  shift(@ARGV);
					  	  last CASE; }
	if ($arg =~ "^-")			{ usage(); }
	push( @args, $arg );
  }
}
@ARGV = @args;

if ($do_all) {
	die( "using --all and search string(s) is a nonsense\n" )	if scalar(@ARGV);
	die( "can't use --all with --rebuild\n" )			if ($do_rebuild);
} else {
	usage()	if (!$do_rebuild && !scalar (@ARGV));
}
	

push( @lookfiles, $localcache );

if ($do_rebuild) {
	foreach my $dir (@rebuildpath) {
		recursedir( $dir )	if (-d $dir);
	}
} else {
	if (-f $localcache) {
		lookfile( $localcache );
	}
	foreach my $dir (@searchpath) {
		recursedir( $dir )	if (-d $dir);
	}
}

process_output();
exit( 0 );


sub recursedir
{
	my ($dir)	= @_;
	my $DIR		= $dir;

	return 	if (-f "$dir/.telno-skip");
	return	if ($dir =~ /\/\./);
	return	if (! -r $dir || ! -x $dir);


	opendir( $DIR, $dir )	or do {
		print STDERR "can't access directory $dir: $!\n";
		return;
	};
	my @files	= readdir( $DIR );
	closedir( $DIR );

	dprint( "looking in: $dir" );

	foreach my $f (@files) {
		next	if ($f eq ".");
		next	if ($f eq "..");
		if (-d "$dir/$f") {
			recursedir( "$dir/$f" );
		} else {
			if (grep( /^$f$/, @lookfiles )) {
				lookfile( "$dir/$f" );
			}
		}
	}
}



sub lookfile
{
	my ($file) = @_;
	my $IN;
	my ($search, $search1);

	if ($do_rebuild) {
		$search = ".";
	} else {
		if ($do_all) {
			$search = ".";
		} else {
			$search	= $ARGV[0];
			$search	=~ s/[\"\',;\.\-_]//g;
			if (defined $ARGV[1]) {
				$search1	= $ARGV[1];
	   			$search1	=~ s/[\"\',;\.\-_]//g;
			}
		}
	}

	$VERBOSE && print STDERR "  processing file $file\n";

	if ($file =~ /\/google.csv/) {
		open( IN, "iconv -c --from-code UTF-16 --to-code ASCII $file |" ) or do {
			print STDERR "can't read (iconv) $file: $!\n";
			return;
		};
	} else {
		open( IN, "<$file" )	or do {
			print STDERR "can't read $file: $!\n";
			return;
		};
	}

	while (<IN>) {
		chomp();

		my $match	= $_;
		   $match	=~ s/[\"\',;\.\-_]//g;


		next	if ($match !~ /$search/i);
		if ($search1) {
			next	if ($match !~ /$search1/i);
		}

		my $fname	= "";
		my ($tag, $name, $num, $sort);

		if ($extrainfo) {
			$fname	= "$file ";
		}

#Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Group Membership,E-mail 1 - Type,E-mail 1 - Value,E-mail 2 - Type,E-mail 2 - Value,E-mail 3 - Type,E-mail 3 - Value,E-mail 4 - Type,E-mail 4 - Value,E-mail 5 - Type,E-mail 5 - Value,Phone 1 - Type,Phone 1 - Value,Phone 2 - Type,Phone 2 - Value,Phone 3 - Type,Phone 3 - Value,Address 1 - Type,Address 1 - Formatted,Address 1 - Street,Address 1 - City,Address 1 - PO Box,Address 1 - Region,Address 1 - Postal Code,Address 1 - Country,Address 1 - Extended Address,Organization 1 - Type,Organization 1 - Name,Organization 1 - Yomi Name,Organization 1 - Title,Organization 1 - Department,Organization 1 - Symbol,Organization 1 - Location,Organization 1 - Job Description,Website 1 - Type,Website 1 - Value,Custom Field 1 - Type,Custom Field 1 - Value
		if ($file =~ /\/google.csv/) {
			$tag = "G";
			chomp();
			s/"//g;
			s/ +:/:/g;
			@F	= split( /,/ );
			next	if ($F[0] eq "Name");
			my $kk;
			for ( $kk=38; $kk<=48 ; $kk+=2 ) {	
				if (defined $F[$kk] && $F[$kk] ne "" && $F[$kk] =~ /^[0-9+]/) {
					#print ">> kk=$kk >$F[$kk]< >$F[$kk-1]<\n";
					#push( @OUT, "$fname$sort:G:$F[0] $F[11] ($F[$kk-1]):$F[$kk]" );
					$name	= "$F[0] $F[11] ($F[$kk-1])";
					$num	= $F[$kk];
					$sort	= $fname . lc($name);
					push( @OUT, "$sort:$fname$tag:$name:$num" );
				}
			}
			next;
		}
		if ($file =~ /\.csv/) {
			$tag = "C";
			s/"//g;
			s/ +:/:/g;
			@F	= split( /:/ );
			my $sort;
			if (defined $F[1] && defined $F[2] && defined $F[3] && defined $F[4]) {
				#push( @OUT, "${fname}C:$F[1] $F[2]:$F[3]-$F[4]" );
				$name	= "$F[1] $F[2]";
				$num	= "$F[3]-$F[4]";
				$sort	= $fname . lc($name);
				push( @OUT, "$sort:$fname$tag:$name:$num" );
			}
			next;
		}
		if ($file =~ /tel\.txt/ || $file =~ /telefono.txt/) {
			chomp();
			chop()	if (/\r$/);
			$tag	= "T";
			$_	=~ s/://g;
			@F	= split( /\t+/ );
			if (defined $F[0] && defined $F[1]) {
				dprint( " >$F[0]< >$F[1]<" );
				#push( @OUT, "${fname}T:$F[0]:$F[1]" );
				$name	= "$F[0]";
				$num	= "$F[1]";
				$sort	= $fname . lc($name);
				push( @OUT, "$sort:$fname$tag:$name:$num" );
			}
			next;
		}

		if ($file eq $localcache) {
			if ($extrainfo) {
				push( @OUT, "(cache) $_" );
			} else {
				push( @OUT, $_ );
			}
			next;
		}
	}
	close( IN );
}


sub process_output
{
	if ($do_rebuild) {
		$VERBOSE && print( STDERR " writing cache on $localcache ... " );
		my $OUT;
		open( OUT, ">$localcache" ) or die "$Cmd: can't write on $localcache: $!\n";
		print( OUT join( "\n", @OUT ) );
		close( OUT )	or die "$Cmd: error writing on $localcache: $!\n";
		$VERBOSE && print( STDERR " ok\n" );
		$VERBOSE && print( STDERR " sorting $localcache ... " );
		system( "sort", "-i", "-u", "-o", $localcache, $localcache );
		$VERBOSE && print( STDERR " ok\n" );
	} else {
		my %done;
		my ($name, $num, $pfx, $tag );
		foreach $_ (sort @OUT) {
			next	if (defined $done{$_});
			@F	= split( /:/ );
			$tag	= $F[1];
			$num	= $F[3];
			$name	= $F[2];

			$num	=~ s/^00/+/;	# if international pfx, use "+" instead of "00"
			$num	=~ s/^0/+41/;	# if prefix w/out international, assumes swiss

			$pfx	= substr( $num, 0, 3 );
			$num	= substr( $num, 3, 99 );

			$num	=~ s/^[-.]//;

			#printf( "%s %-20s %-54s\n", $F[1], $F[3], $F[2] );
			printf( "%s %-3s %-18s %-54s\n", $tag, $pfx, $num, $name );
			$done{$_} = 1;
		}
	}
}


sub usage
{
	die "
usage:	telno [options] name [name2]	(search mode)
	telno [options] --rebuild 	(to rebuild localcache)

options (in search mode):

  -v|--verbose		verbose
  -D|--debug		debug
  -l|--long		long verbose
  -a|--all		show all entries

options (rebuild):
  --cachefile file	use 'file' as cache file
  --add dir		add 'dir' to rebuild path

* searchpath:  " . join( ":", @searchpath ) . "
* rebuildpath: " . join( ":", @rebuildpath ) . "
* cachefile:   $localcache
\n";
}


sub dprint
{
	return if (!$DEBUG);
	print( STDERR "D> ", @_, "\n" );
	return 1;
}
sub dprintf
{
	return if (!$DEBUG);
	print( STDERR "D> " );
	printf( STDERR @_ );
	return 1;
}
sub darray
{
	my $kk;
	my $out = "";
	my $sep = "";
	for ($kk=0; $kk<=scalar(@_); $kk++) {
		$out .= $sep . "($kk)>" . $_[$kk] . "<";
		$sep = " ";
	}
}
