#!perl -T
use 5.006;
use strict;
use warnings FATAL => 'all';
use Test::More 0.82;

eval 'use Map::Tube::London';
plan skip_all => 'Map::Tube::London required for this test' if $@;

plan tests => 42;

my $tube = Map::Tube::London->new();
my $ret;
sub a2n { return [ map { $_->name() } @{ $_[0] } ]; }

$ret = [ $tube->fuzzy_find( 'Baker Street', objects => 'stations' ) ];
ok($ret, 'Finding Baker Street exactly');
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding Baker exactly') if $ret;

$ret = [ $tube->fuzzy_find( 'Baker',        objects => 'stations' ) ];
is_deeply($ret, [ ], 'Finding Baker exactly should fail');

$ret = [ $tube->fuzzy_find( 'Baker Street', objects => 'stations', method => 'start' ) ];
ok($ret, 'Finding Baker Street at start');
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding Baker at start') if $ret;

$ret = [ $tube->fuzzy_find( 'Baker',        objects => 'stations', method => 'start' ) ];
ok($ret, 'Finding Baker at start');
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding Baker at start') if $ret;

$ret = [ $tube->fuzzy_find( 'Bakerx',       objects => 'stations', method => 'start' ) ];
is_deeply($ret, [ ], 'Finding Bakerx at start should fail');

$ret = [ $tube->fuzzy_find( 'ker',          objects => 'stations', method => 'start' ) ];
is_deeply($ret, [ ], 'Finding ker at start should fail');

$ret = [ $tube->fuzzy_find( 'Baker Street', objects => 'stations', method => 'in' ) ];
ok($ret, 'Finding Baker Street somewhere');
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding Baker somewhere');

$ret = [ $tube->fuzzy_find( 'Baker',        objects => 'stations', method => 'in' ) ];
ok($ret, 'Finding Baker somewhere');
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding Baker somewhere');

$ret = [ $tube->fuzzy_find( 'ker',          objects => 'stations', method => 'in' ) ];
ok($ret, 'Finding ker somewhere');
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding ker somewhere');

$ret = [ $tube->fuzzy_find( 'xer',          objects => 'stations', method => 'in' ) ];
is_deeply($ret, [ ], 'Finding xer somewhere should fail');

$ret = [ $tube->fuzzy_find( '[kx]er',       objects => 'stations', method => 're' ) ];
ok($ret, 'Finding regex [kx]er');
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding regex [kx]er');

$ret = [ $tube->fuzzy_find( '[tx]ers',      objects => 'stations', method => 're' ) ];
ok($ret, 'Finding regex [tx]ers');
is_deeply( a2n($ret), [ 'Cockfosters', 'Seven Sisters' ], 'Finding regex [tx]ers');

$ret = [ $tube->fuzzy_find( 'a[ktx]er',     objects => 'stations', method => 're' ) ];
ok($ret, 'Finding regex a[ktx]er');
is_deeply( a2n($ret), [ 'Baker Street', 'Bayswater', 'Canada Water', 'Waterloo' ], 'Finding regex a[ktx]er');

$ret = [ $tube->fuzzy_find( 'Baker Street', objects => 'stations', method => 'levenshtein', maxdist => 4 ) ];
ok($ret, 'Finding Baker Street fuzzy at max distance 4');
is_deeply( a2n($ret), [ 'Baker Street', 'Bond Street', 'Warren Street' ], 'Finding Baker Street fuzzy at max distance 4');

$ret = [ $tube->fuzzy_find( 'Baker',        objects => 'stations', method => 'levenshtein' ) ];
ok($ret, 'Finding Baker fuzzy');
is_deeply( a2n($ret), [ 'Bank' ], 'Finding Baker fuzzy');

$ret = [ $tube->fuzzy_find( 'Paisvatr',     objects => 'stations', method => 'levenshtein' ) ];
ok($ret, 'Finding Paisvatr fuzzy');
is_deeply( a2n($ret), [ 'Bayswater' ], 'Finding Paisvatr fuzzy');

$ret = [ $tube->fuzzy_find( 'Bxxtree',      objects => 'stations', method => 'levenshtein', maxdist => 4 ) ];
ok($ret, 'Finding Bxxtree fuzzy at max distance 4');
is_deeply( a2n($ret), [ 'Becontree' ], 'Finding Bxxtree fuzzy at max distance 4');

$ret = [ $tube->fuzzy_find( 'Bxxtree',      objects => 'stations', method => 'levenshtein', maxdist => 5 ) ];
ok($ret, 'Finding Bxxtreee fuzzy at max distance 5');
is_deeply( a2n($ret), [ 'Becontree', 'Brixton', 'Bushey', 'Hoxton' ], 'Finding Bxxtree fuzzy at max distance 5');

$ret = [ $tube->fuzzy_find( 'Bxxtree',      objects => 'stations', method => 'levenshtein' ) ];
ok($ret, 'Finding Bxxtree fuzzy at standard max distance');
is_deeply( a2n($ret), [ 'Becontree' ], 'Finding Bxxtree fuzzy at standard max distance');

$ret = [ $tube->fuzzy_find( 'Bxxtree',      objects => 'stations', method => 'levenshtein', maxdist => 3 ) ];
is_deeply($ret, [ ], 'Finding Bxxtree fuzzy at max distance 3 should fail');

$ret = [ $tube->fuzzy_find( 'Baker Street', objects => 'stations', method => 'soundex' ) ];
is_deeply( a2n($ret), [ 'Baker Street', 'Bow Church', 'Buckhurst Hill' ], 'Finding Baker Street based on soundex' );

$ret = [ $tube->fuzzy_find( 'Bkrs', objects => 'stations', method => 'soundex' ) ];
is_deeply( a2n($ret), [ 'Baker Street', 'Bow Church', 'Buckhurst Hill' ], 'Finding Bkrs based on soundex' );

$ret = [ $tube->fuzzy_find( 'Bxqxq', objects => 'stations', method => 'soundex' ) ];
is_deeply( a2n($ret), [ 'Bushey' ], 'Finding Bxqxq based on soundex' );

$ret = [ $tube->fuzzy_find( 'Pxqxq', objects => 'stations', method => 'soundex' ) ];
is_deeply( $ret, [ ], 'Finding Pxqxq based on soundex should fail' );

$ret = [ $tube->fuzzy_find( 'Baker Street', objects => 'stations', method => 'metaphone' ) ];
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding Baker Street based on metaphone' );

$ret = [ $tube->fuzzy_find( 'Bkrstrt', objects => 'stations', method => 'metaphone' ) ];
is_deeply( a2n($ret), [ 'Baker Street' ], 'Finding Bkrstrt based on metaphone' );

$ret = [ $tube->fuzzy_find( 'Bxqxq', objects => 'stations', method => 'metaphone' ) ];
is_deeply( $ret, [ ], 'Finding Bxqxq based on metaphone' );

