package DTA::Controller::API;
use Moose;
use namespace::autoclean;

BEGIN {extends 'Catalyst::Controller'; }

use XML::Atom::Content;
use XML::Atom::Entry;
use XML::Atom::Feed;
use XML::Atom::Link;
use XML::Atom::Person;
use LWP::UserAgent;

=head1 NAME

DTA::Controller::API - Catalyst Controller

=head1 DESCRIPTION

Catalyst Controller.

=head1 METHODS

=head2 index

=cut

sub index :Path :Args(0) {
    my ( $self, $c ) = @_;
    $c->stash(
        template => 'web/api/index.tt',
    );
}

=head2 recent

=cut

sub recent :Local {
    my ( $self, $c ) = @_;

    $c->forward( '/recent' );

    my $feed = XML::Atom::Feed->new( Version => 1.0 );
    $feed->title('Deutsches Textarchiv: Neue Werke');
    $feed->id( 'tag:www.deutschestextarchiv.de,2012-10-05:/recent' );

    my $self_link = XML::Atom::Link->new( Version => 1.0 );
    $self_link->type('application/atom+xml');
    $self_link->rel('self');
    $self_link->href( $c->uri_for('/api/recent') );
    $feed->add_link( $self_link );

    my $i = 0;
    foreach my $book ( @{$c->stash->{web_recent}} ) {
        $i++; last if $i > 20;
        if ( $i == 1 ) {
            $feed->updated( $book->{date_ingest} . "Z" );
        }

        my $entry = XML::Atom::Entry->new( Version => 1.0 );
        $entry->title( $book->{dta_bibl_angabe} );
        $entry->updated( $book->{date_ingest} . "Z" );
        $entry->id( sprintf 'tag:www.deutschestextarchiv.de,%s:/recent/%s', $book->{date_ingest}, $book->{dirname} );

        my $author = XML::Atom::Person->new( Version => 1.0 );
        $author->name( 'Deutsches Textarchiv' );
        $entry->author( $author );

        my $content = XML::Atom::Content->new( Version => 1.0 );
        $content->body( sprintf '<img src="http://media.dwds.de/dta/images/%s/%s_%04d_160px.jpg" />', $book->{dirname}, $book->{dirname}, $book->{startseite} );
        $entry->content( $content );

        my $link = XML::Atom::Link->new( Version => 1.0 );
        $link->type('text/html');
        $link->rel('alternate');
        $link->href( $c->uri_for('/book/show', $book->{dirname}) );
        $entry->add_link( $link );

        $feed->add_entry( $entry );
    }
    my $xml = $feed->as_xml;
    utf8::decode( $xml );

    $c->res->content_type( 'application/atom+xml; charset=utf-8' );
    $c->res->body( $xml );
}

=head2 beacon

=cut

sub beacon :Local {
    my ( $self, $c ) = @_;

    my $rs = $c->model('DTADB::Book')->search({
        'me.ready'   => { -in => [1, 2] },
    });

    my %pnd;
    while( my $book = $rs->next ) {
        foreach my $field ( qw(autor1_pnd autor2_pnd autor3_pnd) ) {
            $pnd{ $book->$field }++ if $book->$field;
        }

        if ( my $publisher = $book->publisher_fw ) {
            foreach my $person ( @$publisher ) {
                $pnd{ $person->{pnd} }++ if $person->{pnd};
            }
        }

        if ( my $translator = $book->translator_fw ) {
            foreach my $person ( @$translator ) {
                $pnd{ $person->{pnd} }++ if $person->{pnd};
            }
        }
    }

    $c->stash(
        template => 'web/api/beacon.tt',
        list     => \%pnd,
        view     => 'Plain',
    );

    $c->res->content_type( 'text/plain; charset=utf-8' );
}

=head2 tei_beacon

=cut

sub tei_beacon :Local {
    my ( $self, $c ) = @_;

    my $rs = $c->model('DTADB::Book')->search(
        {
            'me.ready' => { -in => [1, 2] },
        },
        {
            order_by => 'me.dirname',
        },
    );

    my @files;
    while( my $book = $rs->next ) {
        push @files, $book->dirname;
    }

    $c->stash(
        template => 'web/api/tei_beacon.tt',
        list     => \@files,
        view     => 'Plain',
    );

    $c->res->content_type( 'text/plain; charset=utf-8' );
}

=head2 pnd

=cut

sub pnd :Local {
    my ( $self, $c, $id ) = @_;
    $c->detach( '/default' ) unless $id;

    $c->req->params->{'select-1'} = 'pnd';
    $c->req->params->{'search-1'} = $id;
    $c->req->params->{search}     = 1;

    $c->go( '/search/metadata' );
}

=head2 cmdi

Get xml from DTAQ [DTAQ::Controller::DTAQ::API]

=cut

sub cmdi :Local {
    my ( $self, $c, $id_or_dirname ) = @_;

    my $book = $c->forward( '/book/validbook', [$id_or_dirname] );
    my $xml =  $c->forward( 'dtaq_api', [ 'cmdi', $book->dirname ]);

    $c->res->content_type( 'text/xml' );
    $c->res->body( $xml );
}

=head2 tei_header

Get xml from DTAQ [DTAQ::Controller::DTAQ::API]

=cut

sub tei_header :Local {
    my ( $self, $c, $id_or_dirname ) = @_;

    my $book = $c->forward( '/book/validbook', [$id_or_dirname] );
    my $xml =  $c->forward( 'dtaq_api', [ 'tei_header', $book->dirname ]);

    $c->res->content_type( 'text/xml' );
    $c->res->body( $xml );
}

=head2 oai_dc

Get xml from DTAQ [DTAQ::Controller::DTAQ::API]

=cut

sub oai_dc :Local {
    my ( $self, $c, $id_or_dirname ) = @_;

    my $book = $c->forward( '/book/validbook', [ $id_or_dirname ] );
    my $xml =  $c->forward( 'dtaq_api', [ 'oai_dc', $book->dirname ]);

    $c->res->content_type( 'text/xml' );
    $c->res->body( $xml );

}

sub news :Local {
    my ( $self, $c ) = @_;

    my $xml =  $c->forward( 'dtaq_api', [ 'news' ]);

    $c->res->content_type( 'application/atom+xml; charset=utf-8' );
    $c->res->body( $xml );
}


=head2

FINAL request to the DTAQ! API to get some data.

So you always need a running DTAQ Backend for this!

See dta.yml, dta_local.yml for configuration.

Is error_404 sufficiant in case of failure, or do we better use 502, 503?

=cut
sub dtaq_api : Private{
    my ( $self, $c, $path_part, $dirname ) = @_;
    $c->detach('/error_404') unless $path_part;
    $c->detach('/error_404') if( ! $dirname && $path_part ne 'news' );

    my $ua = LWP::UserAgent->new;
    $ua->timeout(10);
    my $api_url = sprintf( '%s/dtaq/api/%s/%s', $c->config->{dtaq}->{base_url}, $path_part, $dirname );
    
    my $res = $ua->get( $api_url );
    $c->detach('/error_404') unless $res->is_success;
    return $res->decoded_content;

}

__PACKAGE__->meta->make_immutable;

1;
__END__

=head1 AUTHOR

Frank Wiegand

=head1 LICENSE

This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.

=cut
