# $Id: basic.t,v 1.1 2017/06/13 00:51:28 cmanley Exp $
# This file must be saved in UTF-8 encoding!
use strict;
use warnings;
use Test::More; #qw(no_plan);
use lib qw(../lib);

my %tests_verify_good = (
	'hello'		=> '$2a$10$O0fG6ExZRx4mEZxsRHqPKuDy9U2HW9M4UONC1hnsx84tW/bb5URFO',
	'Test 123'	=> '$2b$10$wOmSB/8mvcXJBAnPTJzO..tFOq4nCxP21vTfWqunrVi5Irsi3Obcy',
	'€U maffia'	=> '$2y$04$f5VgvyHCr0OiPbvjdZ8zJuPBHD6Tul6nleZSWUVkk/HSOKOC8DmFy',	# UTF-8!
);
my %tests_verify_bad = (
	'wrong password'	=> '$2a$10$O0fG6ExZRx4mEZxsRHqPKuDy9U2HW9M4UONC1hnsx84tW/bb5URFO',
	'garbage'			=> '0fG6ExZRx4mEZxsRHqPKuDy9U2HW9M4UONC1hnsx84tsdfs',
);
my @test_passwords = sort(keys(%tests_verify_good), keys(%tests_verify_bad));
my %tests_info = (
	'$2a$10$O0fG6ExZRx4mEZxsRHqPKuDy9U2HW9M4UONC1hnsx84tW/bb5URFO' => {
		'algo'		=> 1, #$class::PASSWORD_BCRYPT,
		'algoName'	=> 'bcrypt',
		'options'	=> {
			'cost'	=> 10,
		},
		'algoSig'	=> '2a',
		'salt'		=> 'O0fG6ExZRx4mEZxsRHqPKu',
		'hash'		=> 'Dy9U2HW9M4UONC1hnsx84tW/bb5URFO',
	},
	'$2b$10$wOmSB/8mvcXJBAnPTJzO..tFOq4nCxP21vTfWqunrVi5Irsi3Obcy' => {
		'algo'		=> 1, #$class::PASSWORD_BCRYPT,
		'algoName' => 'bcrypt',
		'options'	=> {
			'cost'	=> 10,
		},
		'algoSig'	=> '2b',
		'salt'		=> 'wOmSB/8mvcXJBAnPTJzO..',
		'hash'		=> 'tFOq4nCxP21vTfWqunrVi5Irsi3Obcy',
	},
	'$2y$04$f5VgvyHCr0OiPbvjdZ8zJuPBHD6Tul6nleZSWUVkk/HSOKOC8DmFy' => {
		'algo'		=> 1, #$class::PASSWORD_BCRYPT,
		'algoName' => 'bcrypt',
		'options'	=> {
			'cost'	=> 4,
		},
		'algoSig'	=> '2y',
		'salt'		=> 'f5VgvyHCr0OiPbvjdZ8zJu',
		'hash'		=> 'PBHD6Tul6nleZSWUVkk/HSOKOC8DmFy',
	},
	'yabadabadoo' => {
		'algo'		=> 0,
		'algoName'	=> 'unknown',
		'options'	=> {},
	},
);

my $class = 'PHP::Functions::Password';

my @methods = map { $_, "password_$_"; } qw(
	get_info
	hash
	verify
);

plan tests => 1 + scalar(@methods) + scalar(keys(%tests_verify_good)) + scalar(keys(%tests_verify_bad)) + scalar(@test_passwords) + scalar(keys(%tests_info));

require_ok($class) || BAIL_OUT("$class has errors");
foreach my $method (@methods) {
	can_ok($class, $method);
}

foreach my $password (sort keys %tests_verify_good) {
	my $crypted = $tests_verify_good{$password};
	my $result = $class->verify($password, $crypted);
	ok($result, "verify password \"$password\" with given crypt string \"$crypted\"");
}

foreach my $password (sort keys %tests_verify_bad) {
	my $crypted = $tests_verify_bad{$password};
	my $result = $class->verify($password, $crypted);
	ok(!$result, "expect fail from verify password \"$password\" with invalid crypt string \"$crypted\"");
}

foreach my $password (@test_passwords) {
	my $crypted = $class->hash($password);
	my $result = $class->verify($password, $crypted);
	ok($result, "verify password \"$password\" with generated crypt string \"$crypted\"");
}

foreach my $crypted (sort keys %tests_info) {
	my $expect = $tests_info{$crypted};
	my $info = $class->get_info($crypted);
	is_deeply($info, $expect, "get_info(\"$crypted\")");
}



unless($ENV{'HARNESS_ACTIVE'}) {
	#foreach my $password (sort keys %tests) {
	#	my $hash = $tests{$password};
	#	print "verify $password + $hash = ";
	#	my $result = $class->verify($password, $hash);
	#	print "$result\n";
	#}
    #
	#foreach my $password (sort keys %tests) {
	#	my $hash = $tests{$password};
	#	my $result = $class->hash($password);
	#	print "hash $password = $result\n";
	#}
	#require Data::Dumper; Data::Dumper->import('Dumper'); local $Data::Dumper::Terse = 1;
	#foreach my $crypted (sort keys %tests_info) {
	#	my $info = $class->get_info($crypted);
	#	print "Info $crypted: " . Dumper($info);
	#}
}
exit(0);
