#!/usr/bin/perl 
#$Revision: 1.3 $$Date: 2007/02/19 02:04:33 $$Author: boumenot $
#######################################################################
#######################################################################

package main;
require 5.008_001;

use Getopt::Long;
use IO::File;
use Pod::Usage;
use LWP::Simple;
use Text::Template;
use Data::Dumper;
use File::Path;
use XML::Simple;

use strict;
use warnings;

use constant AWS4_ONLINE_HTML => {
    '2007-10-29' => 'http://docs.amazonwebservices.com/AWSECommerceService/2007-10-29/DG/',
};

use constant AWS4_LOCALE_HTML => {
    'us' => 'USSearchIndexParamForItemsearch.html',
    'de' => 'DESearchIndexParamForItemsearch.html',
    'jp' => 'JPSearchIndexParamForItemsearch.html',
    'uk' => 'UKSearchIndexParamForItemsearch.html',
    'fr' => 'FRSearchIndexParamForItemsearch.html',
    'ca' => 'CASearchIndexParamForItemsearch.html',
};

my $Opt_Debug = 0;
my $Opt_Dest = "../lib/Net/Amazon/Validate/ItemSearch";
my $Opt_Overwrite = 0;

unless (&GetOptions (
		     "help|h"	 => \&usage,
		     "version|V" => \&version,
		     "debug|D"   => \$Opt_Debug,
             "dest=s"    => \$Opt_Dest,
		     "overwrite" => \$Opt_Overwrite,
		     "<>"	     => \&parameter,
		     )) {
    usage();
}

## main #########################################

unless (-d $Opt_Dest) {
    die "The directory $Opt_Dest does not exist!\n";
}


for my $locale (keys %{(AWS4_LOCALE_HTML)}) {
    my %upc;
    for my $ver (keys %{(AWS4_ONLINE_HTML)}) {
        my %depts;
        my $link =  AWS4_ONLINE_HTML->{$ver}.AWS4_LOCALE_HTML->{$locale};
        print "fetching $link ...\n" if $Opt_Debug;

        my $xhtml = get($link);
        die "%Error: failed to fetch '$link'!\n" 
            unless $xhtml;

        my $xs = XML::Simple->new(ForceArray => [qw(li)]);
        my $href = $xs->XMLin($xhtml);

        for my $divI (@{$href->{body}->{div}}) {
            for my $divJ (@{$divI->{div}}) {
                next unless defined $divJ->{class} and $divJ->{class} eq 'section';

                my @a = @{$divJ->{div}};
                my $hdr = shift @a;

                next if scalar(@a) < 1;
                next unless defined $hdr->{div}->{div}->{h2}->{content};
                next unless $hdr->{div}->{div}->{h2}->{content} =~ m/^SearchIndex: (\w+)/;

                my $dept = $1;
                next if $dept eq 'All';

                for my $col (@a) {
                    for my $td (@{$col->{table}->{tbody}->{tr}->{td}}) {
                        for my $li (@{$td->{div}->{ul}->{li}}) {
                            #push @{$depts{$dept}}, $li->{p};
                            push @{$depts{$li->{p}}}, $dept;
                        }
                    }
                    # GRRR: amazon.com should be more consistent.
                    for my $li (@{$col->{ul}->{li}}) {
                        #push @{$depts{$dept}}, $li->{p};
                        push @{$depts{$li->{p}}}, $dept;
                    }
                }
            }
        }

        for my $dept (keys %depts) {
            dump_library($depts{$dept}, $locale, $dept);
            upc_add(\%upc, $depts{$dept});
        }
    }
    my @a = keys %upc;
    my $type = ($locale eq 'us') ? 'UPC' : 'EAN';
    dump_library(\@a, $locale, $type);
}

## subs #########################################

sub usage {
    print '$Revision: 1.3 $$Date: 2007/02/19 02:04:33 $$Author: boumenot $ ', "\n";
    pod2usage(-verbose=>2, -exitval => 2);
    exit (1);
}

sub version {
    print '$Revision: 1.3 $$Date: 2007/02/19 02:04:33 $$Author: boumenot $ ', "\n";
    exit (1);
}

sub parameter {
    my $param = shift;
    die "%Error: Unknown parameter: $param\n";
}

##################################################

# Attempt to pick a "favored" default for the different types of
# ItemSearch'es.  The favored list is returned in order of preference.
# The most preferred is Books because that was the default for AWS3.  As
# Books is not available for all types of ItemSearch'es use other
# "favored" defaults.  They are Music, DVD, and Software in that order.
# If none of those are a possible default then use the first item in
# the list of acceptable values.

sub select_default {
    my $aref = shift;

    for my $favored_default (qw(Books Music DVD Software)) {
        return $favored_default if grep {$favored_default eq $_} @$aref;
    }

    return $aref->[0];
}

sub upc_add {
    my ($href, $aref) = @_;
    $href->{$_}++ for @$aref;
}

sub dump_library {
    my ($aref, $locale, $dept) = @_;

    my $fn = "$Opt_Dest/$locale/$dept.pm";
    my $dn = "$Opt_Dest/$locale";

    unless (-d $dn) {
        mkpath $dn or die "Failed to create '$dn'!\n";
    }

    if (-f $fn && !$Opt_Overwrite) {
        warn "The file $fn already exists, skipping!\n";
        return;
    }

    my $template = Text::Template->new(
            TYPE       => 'FILE',
            SOURCE     => 'aws4-itemsearch.tmpl',
            DELIMITERS => [ '[%--', '--%]', ],
    );

    my $hash = {'MODULE_NAME'    => "$locale".'::'."$dept",
                'DEFAULT_OPTION' => select_default(\@$aref),
                'options'        => \@$aref,
    };

    my $text = $template->fill_in(HASH => $hash);
    unless ($text) {
        die "Failed to fill in the text template for $locale/$dept!\n";
    }

    my $fouth = IO::File->new(">$fn") or
        die "$! '$fn'!\n";

    print $fouth $text;

    $fouth->close();
}


##################################################
__END__

=pod

=head1 asw4-itemsearch

B<asw4-types> - convert Amazon's HTML data to Perl libraries to pick ItemSearch
defaults.

=head1 SYNOPSIS

B<asw4-itemsearch> - [I<OPTION>]... [I<FILE>]...

=head1 DESCRIPTION

B<asw4-itemsearch> converts the data stored in Amazon's HTML pages for
ASW4 into Perl libraries.  These libraries are used by Net::Amazon to
validate user input, and select default entries for ItemSearch
operations.

=head1 ARGUMENTS

=over 4

=item -h, --help

Displays this message and program version and exits.

=item -V, --version

Displays the program's version and exits.

=item -D, --debug

Prints debug information.

=item --overwrite

Overwrite any libraries if they already exist.

=item --dest E<lt>directoryE<gt>

Specify the destination where the files should be written.

=back

=head1 AUTHORS

Written by Christopher Boumenot.

=head1 REPORTING BUGS

Report bugs to <boumenot@gmail.com>.

=head1 SEE ALSO

=cut

