#!/usr/bin/env perl
#
#  Convert names in v3 to names in v4
#
#  Usage: ./rewrite_attribute_names -D dict_dir file
#
#  @todo - also do internal attributes, but their OIDs have changed :(
#  maybe just have 
#
######################################################################
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#
#    Copyright (C) 2021 Network RADIUS SARL (legal@networkradius.com)
#
######################################################################
#
#  $Id: 1f746ed1e4bd4662a9033871e6325e6b1257623d $
#
#  ./scripts/upgrade/rewrite_attribute_names  -D ./share/dictionary/ -a attrs -i file -o file

#
#
# v3 create aliases file for ingestion by v4:
#
#  rm -rf alias;mkdir alias;./build/make/jlibtool --mode=execute ./build/bin/radattr  -D ./share/ -A  | sort -n -k6 -k7 -k8 -k9 -k10 -k11 | gawk '{printf "%s\t%-40s\t%s\n", $1, $2, $3 >> "alias/alias." tolower($5) }'
#
# v4 create attr to oid file for this program:
#
#  (./build/make/jlibtool --mode=execute ./build/bin/local/radict  -f -p radius -D share/dictionary/ 2>&1) | egrep '26\.' | egrep -v internal > attrs
#
#
use strict;
use warnings;
use Getopt::Std;
my $dictdir;
my $protocol;
my $dir;
my $debug = 0;

my %oid_to_v3;
my %oid_to_v4;
my  %v3_to_v4;

our $opt_a = "./attrs";
our $opt_D = "./share/dictionary";
our $opt_i = "";
our $opt_o = "";
our $opt_p = "radius";
our $opt_x = 0;

#
#  read dictionary/alias/*, and build
#    set name to OID and OID to name mappings
#
#  Read dictionary.foo, but not dictionary.rfc
#    set look up OID and set to new name
#
#  loop over input file, breaking into words specified by the
#  dictionary character list.
#
#  replace where found.
#
sub read_v4_alias {
    my $filename = shift;

    open(my $FILE, "<", $filename) or die "Failed to open $filename: $!\n";

    while (<$FILE>) {
	next if ! /^ALIAS/;

	my @fields = split /\s+/;

#	print join(',', @fields), "\n";
#	print "v3OID\t", $fields[2], "\t = ", $fields[1], "\n";

	$oid_to_v3{$fields[2]} = $fields[1];
    }

    close $FILE;
}

sub read_v4_oid {
    my $filename = shift;

    open(my $FILE, "<", $filename) or die "Failed to open $filename: $!\n";

    while (<$FILE>) {
	next if ! /^ATTRIBUTE/;

	my @fields = split /\s+/;

	$oid_to_v4{$fields[2]} = $fields[1];

	if (! defined $oid_to_v3{$fields[2]}) {
#	    print "Missing ", $fields[1], "\t", $fields[2], "\n";

	} else {
	    if ($debug > 0) {
		print $oid_to_v3{$fields[2]}, "\t-->\t", $fields[1], "\n";
	    }

	    $v3_to_v4{$oid_to_v3{$fields[2]}} = $fields[1];
	}
    }

    close $FILE;
}

#
#  Loop over the input file, breaking into words based on dictionary characters.
#
sub process_file {
    local *IN = shift;
    local *OUT = shift;

    while (<IN>) {
	my @array = split /([-A-Za-z0-9\/_]+)/;

	#    print join(',',@array), "\n";

	foreach my $word (@array) {
	    next if !defined $word;

	    my $v4 = $v3_to_v4{$word};
	    if (defined $v4) {
		print OUT $v4;
	    } else {
		print OUT $word;
	    }
	}
    }
}

#
#  Start of the program - get options
#
getopts('a:D:i:o:p:x');
$dictdir = $opt_D;
$protocol = $opt_p;
$debug++ if $opt_x == 1;


$dir = $dictdir . "/" . $protocol . "/alias";

#
#  Read all of the ALIAS files generated by radattr in v3.
#
opendir(my $dh, $dir) || die "Can't opendir $dir: $!";
while (readdir($dh)) {
    next if ! /^alias/;
    next if ! -f "$dir/$_";

    read_v4_alias($dir . "/" . $_);
}
closedir $dh;

#
#  Read the ATTRIBUTE dumps generated by "radict -f -p radius" in v4
#
read_v4_oid($opt_a);

#
#  Now that we have all of the attributes defined, let's process the input file.
#
if ($opt_i ne "") {
    open INPUT, "<$opt_i"  or die "Couldn't open $opt_i: $!";
} else {
    open INPUT, "<&STDIN"  or die "Couldn't dup STDIN: $!";
}

if ($opt_o ne "") {
    open OUTPUT, ">$opt_o"  or die "Couldn't open $opt_o: $!";
} else {
    open OUTPUT, ">&STDOUT"  or die "Couldn't dup STDOUT: $!";
}

#
#  Process the data.
#
process_file(*INPUT, *OUTPUT);

close INPUT;
close OUTPUT;

return 0;
