#!/usr/bin/perl
################################################################################
# Script to convert records at Messenger College Texas:
# - Convert holdings.
# - Copy data to holding from other fields/subfields.
# - Split holdings:
#   + from multiple barcodes in the same field,
#   + from multiple barcodes concatenated in the same subfields, with and 
#     without separator.
################################################################################

use strict;
use Getopt::Std;
use MARC::File::USMARC;
use MARC::Field;

my %options = ();
getopts("h:m:i:o:",\%options);
my $f852 = $options{h};
my $map = $options{m};
my $in = $options{i};
my $out = $options{o};
if (!$map || !$in || !$out) {
    print <<_STR_;
Usage: $0 -h HOLDING_MAP -m MAP -i INFILE -o OUTFILE
Example: $0 -h 949ap,949f9,999bb -m 050ak,050bh,052hm -i in.mrc -o /out.mrc
_STR_
    exit 1;
}

my $marcFile = MARC::File::USMARC->in($in);
open OUT, ">$out";
while (my $rec = $marcFile->next) {
    $rec = convert_holding($rec, $f852);
    $rec = copy_data($rec, $map);
    $rec = split_barcodes($rec);

    print OUT $rec->as_usmarc;
}
close OUT;
$marcFile->close;

exit 0;
################################################################################


sub convert_holding {
    my ($rec, $f852) = @_;

    my ($tag, $code, $f852_code);
    foreach my $h_map (split(/,/, $f852)) {
        $h_map =~ m/(\d{3})(\w)(\w)/;
        $tag = $1;
        $code = $2;
        $f852_code = $3;

        foreach my $f ($rec->field($tag)) {
            $f->set_tag("852");

            my @sf_data = $f->subfield($code);

            $f->delete_subfield(code => $code);
            foreach my $sf (@sf_data) {
                $f->add_subfields($f852_code => $sf);
            }
        }
    }

    return $rec;
}
############################################################


sub copy_data {
    my ($rec, $map) = @_;

    my ($tag, $code, $f852_code, $data);
#    print "$map\n";
    foreach my $m (split(/,/, $map)) {
#        print "$m\n";
        $m =~ m/(\d{3})(\w)(\w)/;
        $tag = $1;
        $code = $2;
        $f852_code = $3;

        $data = $rec->subfield($tag, $code);
        next unless $data;

        foreach my $f ($rec->field("852")) {
#            print "$tag :: $code :: $f852_code\n",$f->as_formatted(),"\n";
            if ($f->subfield($f852_code)) {
                $f->update($f852_code => $data);
            }
            else {
                $f->add_subfields($f852_code => $data);
            }
        }
    }

    return $rec;
}
############################################################


sub split_barcodes {
    my ($rec) = @_;

    my @f852_ps;
    my @barcodes;
    my @f852s;
    foreach my $f ($rec->field("852")) {
        @f852_ps = $f->subfield("p");
        $f->delete_subfield(code => "p");

        $rec->delete_fields($f);
#        print $f->as_usmarc, "\n";

        @barcodes = ();
        foreach my $f852_p (@f852_ps) {
            while ($f852_p =~ s/([a-z]+[\d]+)//i) {
                push @barcodes, $1;
            }
        }

        @f852s = ();
        foreach my $bc (@barcodes) {
            my $f852 = $f->clone();
            $f852->add_subfields("p" => $bc);

            push @f852s, $f852;
        }

        $rec->append_fields(@f852s);
    }

    return $rec;
}
