#!/usr/bin/env perl
use strict;
use warnings;
use Data::Password::zxcvbn;
use Getopt::Long qw(:config
                    posix_default no_require_order
                    auto_version auto_help
               );
our $VERSION = '1.1.3'; # VERSION
# PODNAME: zxcvbn-password-strength
# ABSTRACT: evaluate password strength


my ($json,@from,%user_input);
GetOptions(
    'json|j!' => \$json,
    'from|f=s' => \@from,
    'input|i=s' => \%user_input,
);

if ($json) {
    require JSON::MaybeXS;
    $json = JSON::MaybeXS->new(
        ascii => 1,
        pretty => 1,
        canonical => 1,
        allow_blessed => 1,
        convert_blessed => 1,
    );
}

sub check_one {
    my ($password) = @_;
    my $strength = Data::Password::zxcvbn::password_strength(
        $password,
        { user_input => \%user_input },
    );
    if ($json) {
        print $json->encode({
            password => $password,
            strength => $strength,
        }),",\n";
    }
    else {
        print $password, ' -> ',$strength->{score},"\n";
    };
}

check_one($_) for @ARGV;
for my $file (@from) {
    open my $fh,'<:utf8',$file or die "Can't open $file: $!";
    while (my $password = <$fh>) {
        chomp $password;
        next unless $password;
        check_one($password);
    }
}

__END__

=pod

=encoding UTF-8

=head1 NAME

zxcvbn-password-strength - evaluate password strength

=head1 VERSION

version 1.1.3

=head1 SYNOPSIS

  zxcvbn-password-strength [options] [password...]

Options:

=over 4

=item C<< --input <field>=<value> >>

=item C<< -i <field>=<value> >>

provides names and values that should be considered "obvious guesses",
e.g. account name, user's real name, company name

=item C<--json>

=item C<-j>

output a stream of JSON objects with full details for each password;
without this option, only the password and its score will be printed

=item C<< --from <file> >>

=item C<< -f <file> >>

opens the given C<file> and treats each line as a password to
evaluate; can be given more than once

=item C<--help>

prints this help message and exits

=item C<--version>

prints the script version and exits

=back

=head1 AUTHOR

Gianni Ceccarelli <gianni.ceccarelli@broadbean.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2022 by BroadBean UK, a CareerBuilder Company.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
