#------------------------------------------------------------
# Copyright (C) 2008 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package Distribution::Catalog::CountryList;
use strict;
use warnings;

use Data::Dumper;
use List::Compare;

use lib '/app/tools/common/lib';
use Common::XMLObject;
use Common::Assert;
use Common::UTF8;

use lib '/app/tools/distribution/lib';

use base 'Common::XMLObject';

use constant kCountries => qw(
  AF AX AL DZ AS AD AO AI AQ AG AR AM AW AU AT AZ BS BH BD BB BY BE
  BZ BJ BM BT BO BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL
  CN CX CC CO KM CG CD CK CR CI HR CU CY CZ DK DJ DM DO EC EG SV GQ
  ER EE ET FK FO FJ FI FR GF PF TF GA GM GE DE GH GI GR GL GD GP GU
  GT GG GN GW GY HT HM VA HN HK HU IS IN ID IR IQ IE IM IL IT JM JP
  JE JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW
  MY MV ML MT MH MQ MR MU YT MX FM MD MC MN ME MS MA MZ MM NA NR NP
  NL AN NC NZ NI NE NG NU NF MP NO OM PK PW PS PA PG PY PE PH PN PL
  PT PR QA RE RO RU RW SH KN LC PM VC WS SM ST SA SN RS SC SL SG SK
  SI SB SO ZA GS ES LK SD SR SJ SZ SE CH SY TW TJ TZ TH TL TG TK TO
  TT TN TR TM TC TV UG UA AE GB US UM UY UZ VU VE VN VG VI WF EH YE
  ZM ZW CS BL MF
);

use constant kRegions => qw( );

sub _init {
    my ( $self, %args ) = @_;

    $self->SUPER::_init(%args);

    $self->{_allowed} = $args{allowed};
    $self->{_denied}  = $args{denied};

    my @countries = (kCountries);
    $self->{_countries} = \@countries;

    my @regions = (kRegions);
    $self->{_regions} = \@regions;

    return $self;
}

sub CountriesOnly {
    my $self  = shift;
    my $param = shift;

    if ( defined($param) ) {
        $self->{_countries_only} = $param;
    }

    return $self->{_countries_only};
}

sub RequireAllowed {
    my $self  = shift;
    my $param = shift;

    if ( defined($param) ) {
        $self->{_require_allowed} = $param;
    }

    return $self->{_require_allowed};
}

sub Allowed {
    my $self = shift;

    if ( $self->RequireAllowed() && !$self->{_allowed} ) {
        Common::Log::Debug(" - No allowed, returning inverted deny");
        return $self->InvertDenied();
    }

    if ( $self->CountriesOnly() ) {
        Common::Log::Debug(" - Return allowed, without regions");
        return $self->RemoveRegions( $self->{_allowed} );
    }

    if ( $self->{_allowed} && ref( $self->{_allowed} ) eq 'ARRAY' ) {
        Common::Log::Debug(" - Return raw allowed, it's a list ref");
        return $self->{_allowed};
    }

    if ( $self->{_allowed} && !ref( $self->{_allowed} ) ) {
        Common::Log::Debug(" - Return allowed, coersed into list");
        return [ $self->{_allowed} ];
    }

    Common::Log::Debug(" - Allowed list must be empty");
    return undef;
}

sub Denied {
    my $self = shift;

    if ( $self->RequireAllowed() ) {
        Common::Log::Debug(" - Allowed required, returning empty list");
        return undef;
    }

    if ( $self->CountriesOnly() ) {
        Common::Log::Debug(" - Return denied, without regions");
        return $self->RemoveRegions( $self->{_denied} );
    }

    if ( $self->{_denied} && ref( $self->{_denied} ) eq 'ARRAY' ) {
        Common::Log::Debug(" - Return raw denied, it's a list ref");
        return $self->{_denied};
    }

    if ( $self->{_denied} && !ref( $self->{_denied} ) ) {
        Common::Log::Debug(" - Return denied, coersed into list");
        return [ $self->{_denied} ];
    }

    Common::Log::Debug(" - Denied list must be empty");
    return undef;
}

sub Countries {
    my $self      = shift;
    my @countries = @_;
    my $lc;
    my @list;

    if (@countries) {
        $self->{_countries} = \@countries;

        if ( $self->{_allowed} ) {
            $lc               = new List::Compare( $self->{_countries}, $self->{_allowed} );
            @list             = $lc->get_intersection();
            $self->{_allowed} = \@list;
        }

        if ( $self->{_denied} ) {
            $lc              = new List::Compare( $self->{_countries}, $self->{_denied} );
            @list            = $lc->get_intersection();
            $self->{_denied} = \@list;
        }
    }

    return $self->{_countries};
}

sub Regions {
    my $self = shift;

    return $self->{_regions};
}

sub All {
    my $self      = shift;
    my @countries = $self->{_countries} ? @{ $self->{_countries} } : ();
    my @regions   = $self->{_regions} ? @{ $self->{_regions} } : ();

    push( @countries, @regions );

    return \@countries;
}

sub InvertDenied {
    my $self = shift;

    return unless ( $self->{_denied} );

    my $countries = $self->CountriesOnly    ? $self->Countries : $self->All;
    my $denied    = ref( $self->{_denied} ) ? $self->{_denied} : [ $self->{_denied} ];

    my $lc = new List::Compare( $countries, $denied );

    my @inverted = $lc->get_unique();

    return \@inverted;
}

sub RemoveRegions {
    my $self = shift;
    my $targetList = shift || return;

    return unless ( $self->Regions() );

    my $lc = new List::Compare( $targetList, $self->Regions() );

    my @list = $lc->get_unique();

    return \@list;
}

1;
