package Data::Password::zxcvbn::Match::BruteForce;
use Moo;
with 'Data::Password::zxcvbn::Match';
use List::AllUtils qw(max);
our $VERSION = '1.1.3'; # VERSION
# ABSTRACT: special match class for brute-force guesses


my $BRUTEFORCE_CARDINALITY = 10;

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

    return $BRUTEFORCE_CARDINALITY ** length($self->token);
}

around guesses_for_password => sub {
    my ($orig,$self,$password) = @_;

    # small detail: make bruteforce matches at minimum one guess bigger than
    # smallest allowed submatch guesses, such that non-bruteforce submatches
    # over the same [i..j] take precedence.
    my $min_guesses = $self->_min_guesses()+1;
    my $guesses = $self->guesses();

    return max($min_guesses,$guesses);
};


around BUILDARGS => sub {
    my ($orig,$class,@args) = @_;
    my $args = $class->$orig(@args);

    $args->{token} = substr(
        delete $args->{password},
        $args->{i},
        $args->{j} - $args->{i} +1,
    );

    return $args;
};

sub make {
    require Carp;
    Carp::croak('BruteForce is a special case, its ->make constructor should never be called');
}


sub feedback_warning { return undef }
sub feedback_suggestions { return [] }

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Data::Password::zxcvbn::Match::BruteForce - special match class for brute-force guesses

=head1 VERSION

version 1.1.3

=head1 DESCRIPTION

This class represents the guess that a certain substring of a password
can't be guessed any other way than by going through all the
characters combinations one by one.

This kind of matches is not generated by L<<
C<omnimatch>|Data::Password::zxcvbn::MatchList/omnimatch >>: it's used
internally by L<<
C<most_guessable_match_list>|Data::Password::zxcvbn::MatchList/most_guessable_match_list
>> to cover unmatched substrings, and as a fallback in the
calculations.

=head1 METHODS

=head2 C<estimate_guesses>

The number of guesses is exponential on the length of the token.

=head2 C<new>

  my $match = Data::Password::zxcvbn::Match::BruteForce->new(
    password => $password,
    i => 2, j => 5,
  );

Returns a match object covering the substring of C<$password> between
the C<i>th and C<j>th character.

=head2 C<feedback_warning>

=head2 C<feedback_suggestions>

This class does not provide any feedback.

=for Pod::Coverage BUILDARGS
make

=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
