#!/usr/bin/perl -w
# NAME: cmppositions.pl
# AIM: QUITE specicific compare two fgcom positions.txt file
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )
use Cwd;
my $os = $^O;
my $perl_dir = '/home/geoff/bin';
my $PATH_SEP = '/';
my $temp_dir = '/tmp';
if ($os =~ /win/i) {
    $perl_dir = 'C:\GTools\perl';
    $temp_dir = $perl_dir;
    $PATH_SEP = "\\";
}
unshift(@INC, $perl_dir);
require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n";
# log file stuff
our ($LF);
my $pgmname = $0;
if ($pgmname =~ /(\\|\/)/) {
    my @tmpsp = split(/(\\|\/)/,$pgmname);
    $pgmname = $tmpsp[-1];
}
my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt";
open_log($outfile);

# user variables
my $VERS = "0.0.1 2013-03-17";
my $load_log = 0;
my $in_file1 = 'C:\FG\18\fgcom\server\fgcom-data\positions.txt';
#my $in_file1 = 'C:\FG\18\fgcom\data\phonebook.txt';
my $in_file2 = 'C:\FG\18\fgcom-bxns\data\positions.txt';
my $verbosity = 0;
my $out_file = '';
my $avoid_rep_dec = 1; # like 36.1982021666667  -95.8894676666667 or 63.9944598333333  -145.719753166667
# ### DEBUG ###
my $debug_on = 0;
my $def_file = 'def_file';
my $bgntm = time();

### program variables
my @warnings = ();
my $cwd = cwd();

my $max_lnn_len = 0;
my $max_icao_len = 4;
my $max_freq_len = 0;
my $max_lat_len = 0;
my $max_lon_len = 0;
my $max_alt_len = 0;
my $max_type_len = 0;
my $max_name_len = 0;

sub VERB1() { return $verbosity >= 1; }
sub VERB2() { return $verbosity >= 2; }
sub VERB5() { return $verbosity >= 5; }
sub VERB9() { return $verbosity >= 9; }

sub show_warnings($) {
    my ($val) = @_;
    if (@warnings) {
        prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
        foreach my $itm (@warnings) {
           prt("$itm\n");
        }
        prt("\n");
    } else {
        prt( "\nNo warnings issued.\n\n" ) if (VERB9());
    }
}

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg);
    }
    show_warnings($val);
    my $secs = time() - $bgntm;
    prt("Ran for $secs seconds...\n");
    close_log($outfile,$load_log);
    exit($val);
}


sub prtw($) {
   my ($tx) = shift;
   $tx =~ s/\n$//;
   prt("$tx\n");
   push(@warnings,$tx);
}

sub process_in_file($) {
    my ($inf) = @_;
    if (! open INF, "<$inf") {
        pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); 
    }
    my @lines = <INF>;
    close INF;
    my $lncnt = scalar @lines;
    prt("Processing $lncnt lines, from [$inf]...\n");
    my ($line,$inc,$lnn);
    $lnn = 0;
    foreach $line (@lines) {
        chomp $line;
        $lnn++;
        if ($line =~ /\s*#\s*include\s+(.+)$/) {
            $inc = $1;
            prt("$lnn: $inc\n");
        }
    }
}


# 0   1       2           3             4    5           6++
# 00C,122.800,37.20966141,-107.86583645,6684,CTAF/UNICOM,Animas Air Park
sub load_pos_file($) {
    my $fil = shift;
    if (!open( INF, "<$fil" )) {
        pgm_exit(1,"ERROR: Unable to open [$fil]\n");
    }
    my @lines = <INF>;
    close INF;
    my $cnt = scalar @lines;
    prt("Processing $cnt lines from $fil..\n");
    my ($line,@arr,$alen,$lnn);
    my ($i,$icao,$freq,$lat,$lon,$alt,$type,$name,$len);
    $lnn = 0;
    my $csvlen = 6; # old files
    my @records = ();
    my %hicao = ();
    foreach $line (@lines) {
        $lnn++;
        chomp $line;
        $line = trim_all($line);
        $len = length($line);
        next if ($len == 0);
        @arr = split(",",$line);
        $alen = scalar @arr;
        if ($alen < 6) {
            prt("$lnn: Bad line [$line]$alen\n");
            next;
        } elsif ($alen < 7) {
            $csvlen = 6;
        } else {
            $csvlen = 7;
        }
        last;
    }
    foreach $line (@lines) {
        $lnn++;
        chomp $line;
        $line = trim_all($line);
        $len = length($line);
        next if ($len == 0);
        @arr = split(",",$line);
        $alen = scalar @arr;
        if ($alen < $csvlen) {
            prt("$lnn: Bad line [$line]$alen, expected $csvlen\n");
            pgm_exit(1,"");
        } 
        if ($csvlen == 7) {
            $icao = trim_all($arr[0]);
            $freq = trim_all($arr[1]);
            $lat  = trim_all($arr[2]);
            $lon  = trim_all($arr[3]);
            $alt  = trim_all($arr[4]);
            $type = trim_all($arr[5]);
            $name = join(' ', splice(@arr,6));
        } else {
            # assume old CSV
            $icao = trim_all($arr[0]);
            $freq = trim_all($arr[1]);
            $lat  = trim_all($arr[2]);
            $lon  = trim_all($arr[3]);
            $alt  = -1;
            $type = trim_all($arr[4]);
            $name = join(' ', splice(@arr,5));
        }
        if (defined ) {
            prtw("WARNIG:$lnn: DUP ICAO $icao,$freq,$lat,$lon,$alt,$type,$name\n");
            next;
        }
        $hicao{$icao} = $freq;
        if ($avoid_rep_dec) {
            $lat =~ s/66667$/7/;
            $lon =~ s/66667$/7/;
            $lat =~ s/3333$//;
            $lon =~ s/3333$//;
        }
        prt("$lnn: $icao,$freq,$lat,$lon,$alt,$type,$name\n") if (VERB9());
        #              0     1     2    3    4    5     6     7 8
        push(@records,[$icao,$freq,$lat,$lon,$alt,$type,$name,0,$lnn]);
        # get sizes for display
        $len = length($freq);
        $max_freq_len = $len if ($len > $max_freq_len);
        $len = length($lat);
        $max_lat_len = $len if ($len > $max_lat_len);
        $len = length($lon);
        $max_lon_len = $len if ($len > $max_lon_len);
        $len = length($alt);
        $max_alt_len = $len if ($len > $max_alt_len);
        $len = length($type);
        $max_type_len = $len if ($len > $max_type_len);
        $len = length($name);
        $max_name_len = $len if ($len > $max_name_len);
    }
    $len = length($lnn);
    $max_lnn_len = $len if ($len > $max_lnn_len);
    $len = scalar @records;
    prt("File $fil has $len records...\n");
    my %h = ();
    $h{file} = $fil;
    $h{records} = \@records;
    $h{icao} = \%hicao;
    $h{csvlen} = $csvlen;
    return \%h;
}


sub show_freq_dist($$) {
    my ($rh1,$rh2) = @_;
    my ($rr1,$rr2,$cnt1,$cnt2,$csvlen,$csvlen2);
    $rr1 = ${$rh1}{records};
    $rr2 = ${$rh2}{records};
    $csvlen = ${$rh1}{csvlen};
    $csvlen2 = ${$rh2}{csvlen};
    $cnt1 = scalar @{$rr1};
    $cnt2 = scalar @{$rr2};
    my ($i,$ra1,$icao,$freq,@arr);
    my %h1 = ();
    for ($i = 0; $i < $cnt1; $i++) {
        $ra1 = ${$rr1}[$i];
        $icao = ${$ra1}[0];
        $freq = ${$ra1}[1];
        if (!defined $h1{$freq}) {
            $h1{$freq} = 1;
        } else {
            $h1{$freq}++;
        }
    }
    @arr = sort keys %h1;
    my @fgcom00 = ();
    my @fgcom01 = ();
    my @fgcom02 = ();
    my @fgcom03 = ();
    my $com00 = 0;
    my $com01 = 0;
    my $com02 = 0;
    my $com03 = 0;
    foreach $freq (@arr) {
        $i = $h1{$freq};
        #prt("$freq $i\n");
        if ($freq < 118) {
            $com00 += $i;
        } elsif ($freq < 125) {
            $com01 += $i;
        } elsif ($freq < 132) {
            $com02 += $i;
        } else {
            $com03 += $i;
        }
    }
    prt("freq < 118 $com00, freq < 125 $com01, freq < 132 $com02, else $com03\n");
   
    # $load_log = 1;
    pgm_exit(1,"");

}

sub process_in_files() {
    my $rh1 = load_pos_file($in_file1);
    if ((!defined ${$rh1}{file})||(!defined ${$rh1}{records})||(!defined ${$rh1}{icao})||(!defined ${$rh1}{csvlen})) {
        pgm_exit(1,"ERROR: Invalid HASH 1\n");
    }
    my $rh2 = load_pos_file($in_file2);
    if ((!defined ${$rh2}{file})||(!defined ${$rh2}{records})||(!defined ${$rh2}{icao})||(!defined ${$rh1}{csvlen})) {
        pgm_exit(1,"ERROR: Invalid HASH 2\n");
    }
    my ($rr1,$rr2,$cnt1,$cnt2,$csvlen,$csvlen2);
    $rr1 = ${$rh1}{records};
    $rr2 = ${$rh2}{records};
    $csvlen = ${$rh1}{csvlen};
    $csvlen2 = ${$rh2}{csvlen};
    $cnt1 = scalar @{$rr1};
    $cnt2 = scalar @{$rr2};
    #show_freq_dist($rh1,$rh2);
    prt("Compare of $cnt1 with $cnt2 records...\n");
    my ($i,$icao,$freq,$lat,$lon,$alt,$type,$name,$ra1,$lnn);
    my ($j,$icao2,$freq2,$lat2,$lon2,$alt2,$type2,$name2,$ra2,$mat2,$lnn2);
    my ($s,$az1,$az2,$ret); 
    my $fnd = 0;
    #               0     1     2    3    4    5     6     7 8
    #push(@records,[$icao,$freq,$lat,$lon,$alt,$type,$name,0,$lnn]);
    my $missed_cnt = 0;
    my $missed2_cnt = 0;
    my $same_cnt = 0;
    my $diff_cnt = 0;
    my @diff_off = ();
    my $added_ctaf = 0;
    prt("\nScan for ICAO in 1 NOT in 2...\n");
    for ($i = 0; $i < $cnt1; $i++) {
        $ra1 = ${$rr1}[$i];
        $icao = ${$ra1}[0];
        $freq = ${$ra1}[1];
        $lat  = ${$ra1}[2];
        $lon  = ${$ra1}[3];
        $alt  = ${$ra1}[4];
        $type = ${$ra1}[5];
        $name = ${$ra1}[6];
        $lnn  = ${$ra1}[8];
        $fnd = 0;
        for ($j = 0; $j < $cnt2; $j++) {
            $ra2 = ${$rr2}[$j];
            $mat2 = ${$ra2}[7];
            next if ($mat2 > 0);
            $icao2 = ${$ra2}[0];
            if ($icao eq $icao2) {
                $fnd = 1;
                $freq2 = ${$ra2}[1];
                $lat2  = ${$ra2}[2];
                $lon2  = ${$ra2}[3];
                $alt2  = ${$ra2}[4];
                $type2 = ${$ra2}[5];
                $name2 = ${$ra2}[6];
                ${$ra1}[7] = $j + 1;
                ${$ra2}[7] = $i + 1;
                last;
            }
        }
        if ($fnd) {
            # ignore obvious difference between OLD and NEW($alt eq $alt2)
            # and IGNORE airport location differences of LT 1 km
            $ret = fg_geo_inverse_wgs_84($lat, $lon, $lat2, $lon2, \$az1, \$az2, \$s);
            ###if (($freq eq $freq2)&&($lat eq $lat2)&&($lon eq $lon2)&&($type eq $type2)&&($name eq $name2)) {
            if (($freq eq $freq2)&&($s < 1000)&&($type eq $type2)&&($name eq $name2)) {
                $same_cnt++;
            } else {
                $diff_cnt++;
                push(@diff_off,$i);
            }
        } else {
            if ($type eq 'CTAF') {
                $added_ctaf++;
            } else {
                $lnn = ' '.$lnn while (length($lnn) < $max_lnn_len);
                $icao .= ' ' while (length($icao) < 4);
                $freq .= ' ' while (length($freq) < $max_freq_len);
                $lat = ' '.$lat while (length($lat) < $max_lat_len);
                $lon = ' '.$lon while (length($lon) < $max_lon_len);
                $alt = ' '.$alt while (length($alt) < $max_alt_len);
                $type .= ' ' while (length($type) < $max_type_len);
                ###$name .= ' ' while (length($name) < $max_name_len);
                prt("$lnn $icao $freq $lat $lon $alt $type $name\n");
                $missed_cnt++;
            }
        }
    }
    prt("\nScan for ICAO in 2 NOT in 1...\n");
    for ($j = 0; $j < $cnt2; $j++) {
        $ra2 = ${$rr2}[$j];
        $mat2 = ${$ra2}[7];
        next if ($mat2 > 0);

        $icao2 = ${$ra2}[0];
        $freq2 = ${$ra2}[1];
        $lat2  = ${$ra2}[2];
        $lon2  = ${$ra2}[3];
        $alt2  = ${$ra2}[4];
        $type2 = ${$ra2}[5];
        $name2 = ${$ra2}[6];
        $lnn   = ${$ra2}[8];
        $lnn = ' '.$lnn while (length($lnn) < $max_lnn_len);
        $icao2 .= ' ' while (length($icao2) < 4);
        $freq2 .= ' ' while (length($freq2) < $max_freq_len);
        $lat2 = ' '.$lat2 while (length($lat2) < $max_lat_len);
        $lon2 = ' '.$lon2 while (length($lon2) < $max_lon_len);
        $alt2 = ' '.$alt2 while (length($alt2) < $max_alt_len);
        $type2 .= ' ' while (length($type2) < $max_type_len);
        ###$name2 .= ' ' while (length($name2) < $max_name_len);
        prt("$lnn $icao2 $freq2 $lat2 $lon2 $alt2 $type2 $name2\n");
        $missed2_cnt++;
    }

    # show the difference
    prt("\nShow $diff_cnt records that are different...\n");
    foreach $i (@diff_off) {
        $ra1 = ${$rr1}[$i];
        $icao = ${$ra1}[0];
        $freq = ${$ra1}[1];
        $lat  = ${$ra1}[2];
        $lon  = ${$ra1}[3];
        $alt  = ${$ra1}[4];
        $type = ${$ra1}[5];
        $name = ${$ra1}[6];
        $lnn  = ${$ra1}[8];
        $j = ${$ra1}[7] - 1;
        if (($j < 0)||($j > $cnt2)) {
            prt("Skipping invalid offset [$j]\n");
            next;
        }
        $ra2 = ${$rr2}[$j];
        $icao2 = ${$ra2}[0];
        $freq2 = ${$ra2}[1];
        $lat2  = ${$ra2}[2];
        $lon2  = ${$ra2}[3];
        $alt2  = ${$ra2}[4];
        $type2 = ${$ra2}[5];
        $name2 = ${$ra2}[6];
        $lnn = ' '.$lnn while (length($lnn) < $max_lnn_len);
        $icao .= ' ' while (length($icao) < 4);
        $ret = fg_geo_inverse_wgs_84($lat, $lon, $lat2, $lon2, \$az1, \$az2, \$s);
        prt("$lnn $icao ");
        prt("F [$freq] vs [$freq2] ") if ($freq ne $freq2);
        if ($s >= 1000) {
            prt("LL [$lat,$lon] vs [$lat2,$lon2] ")
        }
        prt("T [$type] vs [$type2] ") if ($type ne $type2);
        prt("N [$name] vs [$name2] ") if ($name ne $name2);
        prt("A [$alt] vs [$alt2] ") if (($alt != -1)&&($alt2 != -1)&&($alt != $alt2));
        prt("\n");
    }
    prt("Ignoring $added_ctaf CTAF entries\n") if ($added_ctaf > 0);
    prt("Comp: $cnt1 with $cnt2: same $same_cnt, diff $diff_cnt, missed1in2 $missed_cnt, missed2in1 $missed2_cnt\n");

    $load_log = 1;
}

#########################################
### MAIN ###
parse_args(@ARGV);
###process_in_file($in_file);
process_in_files();
pgm_exit(0,"");
########################################

sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av);
}

sub parse_args {
    my (@av) = @_;
    my ($arg,$sarg);
    while (@av) {
        $arg = $av[0];
        if ($arg =~ /^-/) {
            $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /^-/);
            if (($sarg =~ /^h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } elsif ($sarg =~ /^v/) {
                if ($sarg =~ /^v.*(\d+)$/) {
                    $verbosity = $1;
                } else {
                    while ($sarg =~ /^v/) {
                        $verbosity++;
                        $sarg = substr($sarg,1);
                    }
                }
                prt("Verbosity = $verbosity\n") if (VERB1());
            } elsif ($sarg =~ /^l/) {
                if ($sarg =~ /^ll/) {
                    $load_log = 2;
                } else {
                    $load_log = 1;
                }
                prt("Set to load log at end. ($load_log)\n") if (VERB1());
            } elsif ($sarg =~ /^o/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $out_file = $sarg;
                prt("Set out file to [$out_file].\n") if (VERB1());
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            #$in_file = $arg;
            #prt("Set input to [$in_file]\n") if (VERB1());
        }
        shift @av;
    }

    if ($debug_on) {
        prtw("WARNING: DEBUG is ON!\n");
        #if ((length($in_file) ==  0) && $debug_on) {
        #    $in_file = $def_file;
        #    prt("Set DEFAULT input to [$in_file]\n");
        #}
    }
    if (! -f $in_file1) {
        pgm_exit(1,"ERROR: Unable to find in file [$in_file1]! Check name, location...\n");
    }
    if (! -f $in_file2) {
        pgm_exit(1,"ERROR: Unable to find in file [$in_file2]! Check name, location...\n");
    }
}

sub give_help {
    prt("$pgmname: version $VERS\n");
    prt("Usage: $pgmname [options] in-file\n");
    prt("Options:\n");
    prt(" --help  (-h or -?) = This help, and exit 0.\n");
    prt(" --verb[n]     (-v) = Bump [or set] verbosity. def=$verbosity\n");
    prt(" --load        (-l) = Load LOG at end. ($outfile)\n");
    prt(" --out <file>  (-o) = Write output to this file.\n");
}

# eof - template.pl
