package TestGeoUKPostcode;

use strict;
use warnings;

my @TEST_PCS = (
    { raw => 'X', partial => 1 },
    {   raw          => 'XX1',
        area         => 'XX',
        district     => '1',
        subdistrict  => undef,
        sector       => undef,
        unit         => undef,
        partial      => 1,
        fixed_format => 'XX1     ',
    },
    {   raw          => 'XX11',
        area         => 'XX',
        district     => '11',
        subdistrict  => undef,
        sector       => undef,
        unit         => undef,
        partial      => 1,
        fixed_format => 'XX11    ',
    },
    {   raw          => 'XX1X',
        area         => 'XX',
        district     => '1',
        subdistrict  => 'X',
        sector       => undef,
        unit         => undef,
        partial      => 1,
        fixed_format => 'XX1X    ',
    },
    {   raw          => 'XX1X1',
        area         => 'XX',
        district     => '1',
        subdistrict  => 'X',
        sector       => '1',
        unit         => undef,
        partial      => 1,
        fixed_format => 'XX1X 1  ',
    },
    { raw => 'XX11X1XX' },
    {   raw          => 'QI1 1AA',
        area         => 'QI',
        district     => '1',
        subdistrict  => undef,
        sector       => '1',
        unit         => 'AA',
        fixed_format => 'QI1  1AA',
    },
    {   raw           => 'AB10 1II',
        area          => 'AB',
        district      => '10',
        subdistrict   => undef,
        sector        => '1',
        unit          => 'II',
        fixed_format  => 'AB10 1II',
    },
    {   raw          => 'A1 1AA',
        area         => 'A',
        district     => '1',
        subdistrict  => undef,
        sector       => '1',
        unit         => 'AA',
        strict       => 1,
        fixed_format => 'A1   1AA',
    },
    {   raw          => 'A11 1AA',
        area         => 'A',
        district     => '11',
        subdistrict  => undef,
        sector       => '1',
        unit         => 'AA',
        strict       => 1,
        fixed_format => 'A11  1AA',
    },
    {   raw          => 'AA1 1AA',
        area         => 'AA',
        district     => '1',
        subdistrict  => undef,
        sector       => '1',
        unit         => 'AA',
        strict       => 1,
        fixed_format => 'AA1  1AA',
    },
    {   raw          => 'AA11 1AA',
        area         => 'AA',
        district     => '11',
        subdistrict  => undef,
        sector       => '1',
        unit         => 'AA',
        strict       => 1,
        fixed_format => 'AA11 1AA',
    },
    {   raw          => 'A1A 1AA',
        area         => 'A',
        district     => '1',
        subdistrict  => 'A',
        sector       => '1',
        unit         => 'AA',
        strict       => 1,
        fixed_format => 'A1A  1AA',
    },
    {   raw          => 'AA1A 1AA',
        area         => 'AA',
        district     => '1',
        subdistrict  => 'A',
        sector       => '1',
        unit         => 'AA',
        strict       => 1,
        fixed_format => 'AA1A 1AA',
    },
    {   raw          => 'AB10 1AA',
        area         => 'AB',
        district     => '10',
        subdistrict  => undef,
        sector       => '1',
        unit         => 'AA',
        strict       => 1,
        valid        => 1,
        fixed_format => 'AB10 1AA',
    },
    {   raw              => 'AB99 1AA',
        area             => 'AB',
        district         => '99',
        subdistrict      => undef,
        sector           => '1',
        unit             => 'AA',
        strict           => 1,
        valid            => 1,
        non_geographical => 1,
        fixed_format     => 'AB99 1AA',
    },
    {   raw              => 'BX99 1AA',
        area             => 'BX',
        district         => '99',
        subdistrict      => undef,
        sector           => '1',
        unit             => 'AA',
        strict           => 1,
        valid            => 1,
        non_geographical => 1,
        fixed_format     => 'BX99 1AA',
    },
    {   raw          => 'SE1',
        area         => 'SE',
        district     => '1',
        partial      => 1,
        subdistrict  => undef,
        sector       => undef,
        unit         => undef,
        strict       => 1,
        valid        => 1,
        fixed_format => 'SE1     ',
    },
    {   raw              => 'BF1 1AA',
        area             => 'BF',
        district         => '1',
        partial          => 0,
        subdistrict      => undef,
        sector           => 1,
        unit             => 'AA',
        strict           => 1,
        valid            => 1,
        non_geographical => 1,
        bfpo             => 1,
        fixed_format     => 'BF1  1AA',
    },
    {   raw          => 'AB1 2CD',
        area         => 'AB',
        district     => '1',
        subdistrict  => undef,
        sector       => '2',
        unit         => 'CD',
        fixed_format => 'AB1  2CD',
        valid        => 0,
        strict       => 0,
    },
    {   raw          => 'WC1H 9EB',
        area         => 'WC',
        district     => '1',
        subdistrict  => 'H',
        sector       => '9',
        unit         => 'EB',
        fixed_format => 'WC1H 9EB',
        valid        => 1,
        strict       => 1,
    },
    {   raw          => 'AB1',
        area         => 'AB',
        district     => '1',
        subdistrict  => undef,
        sector       => undef,
        unit         => undef,
        fixed_format => 'AB1     ',
        valid        => 0,
        partial      => 1,
        strict       => 1,
    },
    {   raw          => 'SE1',
        area         => 'SE',
        district     => '1',
        subdistrict  => undef,
        sector       => undef,
        unit         => undef,
        fixed_format => 'SE1     ',
        valid        => 1,
        partial      => 1,
        strict       => 1,
    },
    {   raw          => 'SE1 0LH',
        area         => 'SE',
        district     => '1',
        subdistrict  => undef,
        sector       => '0',
        unit         => 'LH',
        fixed_format => 'SE1  0LH',
        valid        => 1,
        partial      => 0,
        strict       => 1,
    },
    {   raw          => 'WC1H 9',
        area         => 'WC',
        district     => '1',
        subdistrict  => 'H',
        sector       => '9',
        unit         => undef,
        fixed_format => 'WC1H 9  ',
        valid        => 1,
        partial      => 1,
        strict       => 1,
    },
    {   raw              => 'AB99 1AA',
        area             => 'AB',
        district         => '99',
        subdistrict      => undef,
        sector           => '1',
        unit             => 'AA',
        fixed_format     => 'AB99 1AA',
        valid            => 1,
        partial          => 0,
        strict           => 1,
        non_geographical => 1,
    },
    {   raw              => 'BF1 1AA',
        area             => 'BF',
        district         => '1',
        subdistrict      => undef,
        sector           => '1',
        unit             => 'AA',
        fixed_format     => 'BF1  1AA',
        valid            => 1,
        partial          => 0,
        strict           => 1,
        non_geographical => 1,
        bfpo             => 1,
    },
    {   raw          => 'B11',
        area         => 'B',
        district     => '11',
        subdistrict  => undef,
        sector       => undef,
        unit         => undef,
        fixed_format => 'B11     ',
        valid        => 1,
        partial      => 1,
        strict       => 1,
    },
    {   raw          => 'B1 1',
        needs_space  => 1,
        area         => 'B',
        district     => '1',
        subdistrict  => undef,
        sector       => '1',
        unit         => undef,
        fixed_format => 'B1   1  ',
        valid        => 1,
        partial      => 1,
        strict       => 1,
    },

    {   raw          => 'N1 0XX',
        area         => 'N',
        district     => '1',
        subdistrict  => undef,
        sector       => '0',
        unit         => 'XX',
        fixed_format => 'N1   0XX',
        valid        => 1,
        strict       => 1,
    },
    {   raw              => 'N1P 2NG',
        area             => 'N',
        district         => '1',
        subdistrict      => 'P',
        sector           => '2',
        unit             => 'NG',
        fixed_format     => 'N1P  2NG',
        valid            => 1,
        strict           => 1,
        non_geographical => 1,
    },
    {   raw              => 'E2 0HP',
        area             => 'E',
        district         => '2',
        subdistrict      => undef,
        sector           => '0',
        unit             => 'HP',
        fixed_format     => 'E2   0HP',
        valid            => 1,
        strict           => 1,
        non_geographical => 0,
    },
);

sub test_pcs {
    my ( $class, $args ) = @_;

    $args ||= {};
    $args->{partial} ||= 0;

    my @pcs = sort { $a->{raw} cmp $b->{raw} } @TEST_PCS;

    foreach my $filter ( keys %{$args} ) {
        $_->{$filter} //= 0 foreach @pcs;
        @pcs = grep { $_->{$filter} == $args->{$filter} } @pcs;
    }

    foreach my $pc (@pcs) {
        next unless $pc->{area};

        $pc->{outcode} ||= sprintf( "%s%s%s",
            $pc->{area},
            $pc->{district} // '',
            $pc->{subdistrict} || '' );

        $pc->{incode} ||= sprintf(
            "%s%s",    #
            $pc->{sector} // '', $pc->{unit} || ''
        );

    }

    return @pcs;
}

sub get_format_list {
    my ( $class, $pc ) = @_;

    my $tmp = $pc->{raw};

    my @list = ($tmp);

    if ( $tmp =~ m/ / ) {

        $tmp =~ s/ /  /;
        push @list, $tmp;

        unless ( $pc->{needs_space} ) {
            $tmp =~ s/ //g;
            push @list, $tmp;
        }
    }

    return @list;
}

sub get_lc_format_list {
    my ( $class, $pc ) = @_;

    return map {lc} $class->get_format_list($pc);
}

1;

