package Lemonldap::NG::Handler::PSGI::Try;

use strict;
use Mouse;

extends 'Lemonldap::NG::Handler::PSGI::Router';

has 'authRoutes' => (
    is      => 'rw',
    isa     => 'HashRef',
    default => sub { { GET => {}, POST => {}, PUT => {}, DELETE => {} } }
);

has 'unAuthRoutes' => (
    is      => 'rw',
    isa     => 'HashRef',
    default => sub { { GET => {}, POST => {}, PUT => {}, DELETE => {} } }
);

sub addRoute {
    die;
}

sub addAuthRoute {
    my $self = shift;
    $self->routes( $self->authRoutes );
    return $self->SUPER::addRoute(@_);
}

sub addUnauthRoute {
    my $self = shift;
    $self->routes( $self->unAuthRoutes );
    return $self->SUPER::addRoute(@_);
}

sub defaultAuthRoute {
    my $self = shift;
    $self->routes( $self->authRoutes );
    return $self->SUPER::defaultRoute(@_);
}

sub defaultUnauthRoute {
    my $self = shift;
    $self->routes( $self->unAuthRoutes );
    return $self->SUPER::defaultRoute(@_);
}

sub _run {
    my $self = shift;
    $self->rule(1);

    return sub {
        my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] );
        my $res = $self->_authAndTrace( $req, 1 );
        if ( $res->[0] < 300 ) {
            $self->routes( $self->authRoutes );
            $req->userData( $self->api->datas );
        }
        else {
            # Unset headers (handler adds a Location header)
            $self->lmLog(
                "User not authenticated, Try in use, cancel redirection",
                'debug' );
            $req->respHeaders( [] );
            $self->routes( $self->unAuthRoutes );
        }
        return $self->handler($req);
    };
}

1;
__END__

=head1 NAME

=encoding utf8

Lemonldap::NG::Handler::PSGI::Try - Special handler for Lemonldap::NG Portal

=head1 SYNOPSIS

  package My::PSGI;
  
  use base Lemonldap::NG::Handler::PSGI::Try;
  
  sub init {
    my ($self,$args) = @_;
    
    # Declare REST routes for authenticated users (could be HTML templates or
    # methods)
    $self->addAuthRoute ( 'index.html', undef, ['GET'] )
         ->addAuthRoute ( books => { ':book' => 'booksMethod' }, ['GET', 'POST'] );
  
    # Default route (ie: PATH_INFO == '/')
    $self->defaultAuthRoute('index.html');
  
    # Same for unauthenticated users
    $self->addUnauthRoute ( 'login.html', undef, ['GET'] )
         ->addUnauthRoute ( 'login', undef, ['POST'] );
    $self->defaultUnauthRoute('login.html');
   
    # Return a boolean. If false, then error message has to be stored in
    # $self->error
    return 1;
  }
  
  sub booksMethod {
    my ( $self, $req, @otherPathInfo ) = @_;

    # Will be called only if authorisated
    my $userId = $self->userId;
    my $book = $req->params('book');
    my $method = $req->method;
    ...
    $self->sendJSONresponse(...);
  }

=head1 DESCRIPTION

Lemonldap::NG::Handler::PSGI::Try is a L<Lemonldap::NG::Handler::PSGI::Router>
package that maintain 2 REST routers: one for authenticated users and one for
unauthenticated users.

=head1 METHODS

Same as L<Lemonldap::NG::Handler::PSGI::Router> (inherits from
L<Lemonldap::NG::Common::PSGI::Router>) except that:

=over

=item addRoute() must be replaced by addAuthRoute() or addUnauthRoute()

=item defaultRoute() must be replaced by defaultAuthRoute() or defaultUnauthRoute()

=back

Note also that user session datas are available in $req parameter (first argument
received by REST methods):

=over

=item $req->user() returns "whatToTrace" uniq identifier

=item $req->userData() returns a hash reference containing user session datas

=back

=head1 SEE ALSO

See L<Lemonldap::NG::Common::PSGI::Router> for more. You just have to re

=head1 AUTHORS

=over

=item Clement Oudot, E<lt>clem.oudot@gmail.comE<gt>

=item Xavier Guimard, E<lt>x.guimard@free.frE<gt>

=back

=head1 BUG REPORT

Use OW2 system to report bug or ask for features:
L<http://jira.ow2.org>

=head1 DOWNLOAD

Lemonldap::NG is available at
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>

=head1 COPYRIGHT AND LICENSE

=over

=item Copyright (C) 2015-2016 by Xavier Guimard, E<lt>x.guimard@free.frE<gt>

=item Copyright (C) 2015-2016 by Clément Oudot, E<lt>clem.oudot@gmail.comE<gt>

=back

This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see L<http://www.gnu.org/licenses/>.

=cut
