#!/usr/bin/perl -w

use strict;
use lib ".";
use Geda;
use Sch;
use Pcb;
use Opt;
use Data::Dumper;

my ($db_sym, $db_sch, $db_fp, $db_pcb);
my %sym_found;
my %src_found;
my %pcb_found;

sub handle_pcb($$$;$) {
    my $rd = shift // "";
    my $bn = shift;
    my $file = shift;
    my $pre = shift // "";

    my $dirname = Common::dirname($file);
    if (Common::is_same_dir(".", $dirname) && $rd eq "") {
	return;
    }
    #print "handle_pcb(): <$rd> <$bn> <$file>\n";
    print $pre, "Getting $rd $bn\n";
    my @line = Common::read_file($file);
    @line = Pcb::refdes_prefix($rd, @line);
    Common::write_file("subt_$rd$bn", @line);
    print $pre, "  Wrote: subt_$rd$bn\n";
    @line = Pcb::ChSide(@line);
    Common::write_file("subb_$rd$bn", @line);
    print $pre, "  Wrote: subb_$rd$bn\n";
}

sub run($$;$);
sub run($$;$) {
    my $file = shift;
    my $rd = shift; # refdes
    my $pre = shift // "";

    print $pre . "Checking <$file>\n";
    $pre = "  " . $pre;

    my @line = Common::read_file($file);
    my $data = Sch::sch_parse(@line);
    my %Hash = Sch::data2Hash($data);
    #my %Attr = Sch::get_glb_attr($data, \%Hash);
    my @ref_sym = @{$Hash{C}};

    for my $ix (@ref_sym) {
	my $fld = $$data[$ix]{fld};
	my ($type, $x, $y, $selectable, $angle, $mirror, $basename) = @$fld;
	my $ratt = $$data[$ix]{rev_att};
	my $refdes = $$ratt{refdes} // "";
	my $src = $$ratt{source} // "";

	$sym_found{$basename}++;
	next unless $src;
	my $pcb = $src;
	$pcb =~ s/\.sch/.pcb/;
	$src_found{$src}++;
	if (!defined($pcb_found{$pcb})) {
	    $pcb_found{$pcb} = [];
	}
	my $new_rd = "$rd$refdes";
	push @{$pcb_found{$pcb}}, $new_rd;
	my $src_file = Common::filedb_BNtoFull($db_sch, $src);
	my $pcb_file = Common::filedb_BNtoFull($db_pcb, $pcb);
	if (!defined($src_file)) {
	    print "source missing: <$refdes> <$src>\n";
	    next;
	}

	if (defined($pcb_file) && -r $pcb_file) {
	    handle_pcb($new_rd, $pcb, $pcb_file, $pre);
	} else {
	    print $pre . "missing <$pcb>\n";
	    run($src_file, $refdes, $pre);
	}
    }
}

sub main() {
    if (@ARGV < 1) { Opt::usage(0, "find refdes and source attributes in .sch files"); }

    ($db_sym, $db_sch, $db_fp, $db_pcb) = Geda::get_files();

    for my $file (@ARGV) {
	if ($file !~ m/\.sch/) {
	    warn("only run this program on .sch files");
	    next;
	}

	run($file, "");
    }
}

main();

__END__
for my $k (sort keys %pcb_found) {
    my @val = @{$pcb_found{$k}};
    my $file = Common::filedb_BNtoFull($db_pcb, $k);
    if ($file) { print "$file  "; }
    else { print "$k missing  "; }
    print  "<", join("/", @val), ">\n";
}
