#!/usr/bin/perl -w

use strict;
#my $netlist = "gnetlist";
my $netlist = "lepton-netlist";

my %pfx = (
    "" => 1,
    p => -12,
    n => -9,
    u => -6,
    m => -3,
    k => 3,
    M => 6,
);
my %pfxmap = (
    # just something that makes p < n etc.
    p => "d",
    n => "e",
    u => "f",
    m => "g",
    "" => "h", # no prefix, as in 1; 1m < 1 < 1k
    k => "i",
    M => "j",
);
my %part;
my @hdr;

sub sortstr($) {
    my $r = shift;
    my @arr = @$r;

    my $ta = $arr[2];
    my $va = "Z" . $ta;
    if ($ta =~ m/^([0-9.]+)([pnumkM]?)( .*)?/) {
	my $v = $1;
	my $k = $pfxmap{$2};
	my $ext = $3 // "";
	if (!defined($k)) { $k = "h"; }
	$va = sprintf(" %s%7.3f%s", $k, $v, $ext);
    }

    $ta = $arr[3];
    if ($ta =~ m/(.*[a-zA-Z])(\d+)/) {
	$ta = sprintf("%s%02d", $1, $2);
    } elsif ($ta =~ m/([a-zA-Z])/) {
	$ta = sprintf("%s  ", $1);
    } else {
	print STDERR "sortstr <$ta>\n";
    }

    my $str = "$arr[0] $arr[1] $va $ta";
    #print "$str\n";
    #exit(0);
    return $str;
}
sub sort_pfx {
    return sortstr($a) cmp sortstr($b);
}

sub run($) {
    my $file = shift;
    #`echo "device\nfootprint\nvalue" > attribs`;

    #print `$netlist -g bom2 -o $file.list $file`;
    if (!open(FH, "$file.list")) {
	warn("no file $file.list");
	return;
    }
    # I get the following format:
    #   refdes:device:footprint:value:qty
    my $col = 5;
    my @line;
    my $len_sz = 4;
    my @len = (0) x $len_sz;
    while (<FH>) {
	chomp;
	if (m/^refdes/) {
	    @hdr = split(/:/,$_,$col);
	    # I want following order: device footprint value refdes
	    @hdr = @hdr[1,2,3,0];
	    next;
	}
	next if (m/^\./);
	next if (m/^U\?(:unknown)+:\d+$/);
	my @fld = split(/:/, $_, $col);
	if (@fld != $col) {
	    warn("not $col cols <$_>");
	    next;
	}
	pop @fld; # skip quantity which is always eq. number of refdes's
#	$fld[1] =~ s/^resistor$/Resistor/;
	my @refdes = split(/,/,$fld[0]);
	# I want following order: device footprint value refdes
	@fld = @fld[1,2,3];
	for (my $ix = 0; $ix < @fld; $ix++) {
	    my $l = length($fld[$ix]);
	    if ($len[$ix] < $l) {
		$len[$ix] = $l;
	    }
	}
	for my $rd (@refdes) {
	    my $l = length($rd);
	    if ($len[$len_sz-1] < $l) {
		$len[$len_sz-1] = $l;
	    }
	    push @line, [ @fld, $rd ];
	}
    }
    close(FH);
    @line = sort sort_pfx @line;

    my $fmt1 = sprintf("%%-%ds %%-%ds %%-%ds", @len[0..2]);
    my $fmt = $fmt1 . " %s\n";
    if (!open(F1, ">$file.list1")) {
	warn("cannot open output file ($file.list1)");
	return;
    }
    if (!open(F2, ">$file.list2")) {
	warn("cannot open output file ($file.list2)");
	return;
    }
    my $str = "";
    my $key = sprintf($fmt1, @{$line[0]}[0,1,2]);
    printf(F1 $fmt, @hdr);
    printf(F1 "\n");
    printf(F2 $fmt, @hdr);
    printf(F2 "\n");
    for my $l (@line) {
	my @arr = @$l;
	my $k = sprintf($fmt1, @arr[0,1,2]);
	if ($k ne $key) {
	    $str =~ s/ $//;
	    my $cnt = split(" ", $str);
	    printf(F2 "%s %2d %s\n", $key, $cnt, $str);
	    $str = "";
	    $key = $k;
	    print F1 "\n"; # Note: F1 here
	}
	$str .= $arr[3] . " ";
	printf(F1 $fmt, @$l);
    }
    if ($str ne "") {
	$str =~ s/ $//;
	my $cnt = split(" ", $str);
	printf(F2 "%s %2d %s\n", $key, $cnt, $str);
    }
    close(F1);
    close(F2);
    `cat $file.list1 | a2ps -o- -s1 -1 -q -f11 -B   --borders=no > $file.list1.ps`;
    `cat $file.list2 | a2ps -o- -s1 -1 -q -f8 -B -r --borders=no > $file.list2.ps`;
}

sub main() {
    for my $f (@ARGV) {
	run($f);
    }
}

main();
