package RDAS::Fetcher::Mechanize;

use Data::Dumper;

use lib '/app/tools/rdas/lib';
use base 'RDAS::Fetcher';

use lib '/app/tools/common/lib';
use Common::Assert;

use constant kDefaultUserAgent => 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.12)';

#use constant kDefaultUserAgent => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.2) Gecko/20100101 Firefox/41.2';

use constant kRequestTimeout => 30;

sub _validOptions {
    ( qw( userAgent maxRedirect timeout scripter), shift->SUPER::_validOptions() );
}

sub _init {
    my $self = shift;
    my %args = @_;

    return $self->SUPER::_init(@_);
}

sub fetch {
    my $self = shift;

    # LWP::UserAgent throws warnings on some dates when reading cookies.
    #   Day too big - 2932896 > 24855
    #   Sec too big - 2932896 > 11647
    local $SIG{__WARN__} = sub {
        warn @_ unless $_[0] =~ m(^.* too (?:big|small));
    };

    assert( $self->url, "URL Required" );

    $self->{_success}   = undef;
    $self->{_errorCode} = undef;

    my $mech = $self->_getMechObject();
    $mech->agent( $self->userAgent() );

    Log->info( "Fetching content from: " . $self->url );

    # 404 throws an exception, but all other non 200s don't.  weird
    eval { $mech->get( $self->url ) };

    if ( $mech->status == 200 ) {
        $self->{_content} = $mech->content();
        $self->{_success} = 1;
        return $self->content();
    } else {
        if ( $mech->status == 302 ) {
            my $location = $mech->res->header('location');
            Log->debug("Header location: $location");

            $self->{_redirectURL} = $location;
        }

        $self->{_errorCode} = $mech->status();
        Log->notice( "Fetch status not 200: " . $self->errorCode );
        return;
    }

}

sub _getMechObject {
    my $self        = shift;
    my %args        = @_;
    my $defaultArgs = $self->_getMechObjectOptions();

    Log->debug( "Mechanize Defaults: " . Dumper($defaultArgs) );
    Log->debug( "Mechanize Custom Args: " . Dumper( \%args ) );

    foreach my $key ( keys %$defaultArgs ) {
        if ( !defined( $args{$key} ) ) {
            $args{$key} = $defaultArgs->{$key};
        }
    }

    Log->debug( "Mechanize Combined Args: " . Dumper( \%args ) );

    my $mech;
    if ( $self->scripter ) {
        require WWW::Mechanize::Firefox;
        $mech = new WWW::Mechanize::Firefox(%args);
    } else {
        require WWW::Mechanize;
        $mech = new WWW::Mechanize(%args);
    }

    if ( $mech->isa(WWW::Mechanize) ) {
        my $timeout = $self->timeout || kRequestTimeout;
        Log->info(" -- Request timeout: $timeout");
        $mech->timeout($timeout);
    }

    return $mech;
}

sub _getMechObjectOptions {
    my $redirect = shift->maxRedirect;
    $redirect = 0 unless ( defined($redirect) );
    return { max_redirect => $redirect };
}

sub userAgent {
    my $self = shift;

    return $self->{_userAgent} ? $self->{_userAgent} : kDefaultUserAgent;
}

sub redirectURL { shift->{_redirectURL} }

sub forms {
    return shift->_getMechObject(@_)->forms();
}

sub mechanize { shift->_getMechObject(@_) }
1;
