#!/usr/bin/perl
###########################################
# similar
# Mike Schilli, 2003 (m@perlmeister.com)
# Fetch books that are similar to a book
# and spider Amazon to a depth of 1.
###########################################
use warnings;
use strict;

use Net::Amazon;
use Net::Amazon::Request::ASIN;
use Data::Dumper;

use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init($DEBUG);

my $DEPTH = 1;

my $ua = Net::Amazon->new(
    token       => 'YOUR_AMZN_TOKEN',
);

$ARGV[0] = "0201360683";
die "usage: $0 asin\n(use 0201360683 as an example)\n" unless defined $ARGV[0];

print "Finding similar items (depth=$DEPTH) for:\n", 
      asin($ARGV[0]), "\n\n";

for(similars($ua, $ARGV[0], $DEPTH)) {
    print $_->title(), "\n";
}

###########################################
sub similars {
###########################################
    my($ua, $asin, $levels, $found) = @_;

    $found = { } unless defined $found;

    my $req = Net::Amazon::Request::ASIN->new(
        asin  => $asin,
        type  => 'heavy',
    );

        # Response is of type Net::Amazon::ASIN::Response
    my $resp = $ua->request($req);

    if($resp->is_error()) {
        warn "Error: ", $resp->message(), "\n";
        return ();
    }

    my @new = ();

    ($found->{$asin}) = $resp->properties();

    return values %$found if $levels < 1;

    my $prod = $resp->xmlref()->{Details}->{SimilarProducts}->{Product};

    unless(defined $prod) {
        warn "$asin doesn't have similar items defined";
        return values %$found;
    }

    my @plist = ($prod);
    @plist = @{$prod} if ref($prod) eq "ARRAY";

    for(@plist) {
        if(!exists $found->{$_}) {
            $found->{$_}++;
            push @new, $_;
        }
    }
 
    for(@new) {
        similars($ua, $_, $levels-1, $found);
    }

    return values %$found;
}

###########################################
sub asin {
###########################################
    my($asin) = @_;

    my $req = Net::Amazon::Request::ASIN->new(
        asin  => $ARGV[0],
    );

   # Response is of type Net::Amazon::ASIN::Response
   my $resp = $ua->request($req);

   if($resp->is_success()) {
       return $resp->as_string();
   } else {
       die("Error: ", $resp->message(), "\n");
   }
}
