package API::Command::PostRecoverPW;
use strict;
use warnings;

use Apache2::Const qw(OK FORBIDDEN HTTP_OK HTTP_UNAUTHORIZED HTTP_NOT_FOUND HTTP_NOT_IMPLEMENTED);
use POSIX (qw/strftime/);

use lib '/app/tools/appuser/lib';
use AppUser::User::Token;
use AppUser::DB::Item::User;

use lib '/app/tools/api/lib';
use API::Response;
use API::DB::Item::PortalPayee;
use API::DB::Item::PasswordRecovery;
use API::Util;

use base 'API::Command';

sub area { return "user"; }
sub cmd  { return "recoverpw"; }

use constant kPortalHostname     => 'portal.royaltyshare.com';
use constant kPortalURI          => '/w3/resetpw/';
use constant kTokenExpireSeconds => 900;                         # 15 minutes

# Process password recovery

sub execute {
    my ($self) = @_;

    # /resetpw/:token

    my $timedToken = $self->getRouteParam(":token");             # timed token
    my $password   = $self->getInputParam("password");

    my $recovery = API::DB::Item::PasswordRecovery->Lookup( token => $timedToken );
    if ($recovery) {
        my $email  = $recovery->email;
        my $t      = AppUser::User::Token->new( email => $email );
        my $_token = $t->GetToken();

        # make sure the token is valid
        if ( $self->IsValidToken( $timedToken, $_token ) ) {

            my $userObj = AppUser::DB::Item::User->Lookup(
                'email' => $email,
            );

            # Make sure the password complies with our password policy.
            #
            my ( $st, $emsg ) = API::Util->validatePassword($password, $userObj);
            if ( $st != 200 ) {
                return $self->createResponse(
                    status => $st,
                    data   => { msg => API::Util::kInvalidPassword, emsg => $emsg }
                );
            }

            # Before saving the new password, copy the old one to the password history

            my $oldPassword = $userObj->password;
            my $lastChanged = $userObj->last_changed;
            my $userID      = $userObj->user_id;
            $userObj->ArchivePassword( $userID, $oldPassword, $lastChanged );

            # Password is good, let's save it
            #
            $userObj->UpdatePassword( $userID, $password );

            my $now = strftime "%Y-%m-%d %H:%M:%S", localtime time;
            $userObj->last_changed($now);
            $userObj->must_change(0);
            $userObj->save();

            # All done; delete the recovery token
            #
            $recovery->delete();

        } else {
            return $self->createResponse(
                status => HTTP_UNAUTHORIZED,
                data   => { msg => "Token expired" }
            );
        }

    } else {
        return $self->createResponse(
            status => HTTP_NOT_FOUND,
            data   => { msg => "Invalid token" }
        );
    }

    return $self->createResponse(
        status => HTTP_OK,
        data   => { msg => "success" }
    );
}

sub IsValidToken {
    my ( $self, $token2, $myToken ) = @_;

    if ( $token2 && $token2 =~ /^($myToken)(.+)$/ ) {
        my $timeSet = $2;
        if ( $timeSet + kTokenExpireSeconds > time() ) {
            return 1;
        } else {
            return undef;
        }
    } else {
        return undef;
    }
}

1;
