#------------------------------------------------------------
# Copyright (C) 2008 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package Common::Client;

use strict;
use warnings;
use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::FormObject;
use Common::DB::Item::Client;
use Common::RSDB;
use Common::RSApp;
use Common::Locale;
use Common::Assert;

use base 'Common::FormObject';

# The following are bit fields that represent client types.
#
use constant kDigitalAdvantage    => 1;
use constant kArtist              => 2;
use constant kLabel               => 4;
use constant kDistribution        => 8;
use constant kUSMechanicals       => 16;
use constant kUKMechanicals       => 32;
use constant kCAMechanicals       => 64;
use constant kBookPublishing      => 128;
use constant kSalePriceValidation => 256;
use constant kProductMonitoring   => 512;
use constant kPayeePortal         => 1024;

use constant kCachePath => 'Common::ClientSettings';

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

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

    my %properties;
    if ( $args{_dbItem} ) {
        $self->_propertiesFromDBItem( \%properties, $args{_dbItem} );
    } elsif ( $args{clientID} ) {
        $self->_propertiesFromDB( \%properties, $args{clientID} );
    } else {
        $self->_propertiesFromDefaults( \%properties );
    }

    $self->_initProperties( \%properties );

    return $self;
}

sub _propertiesFromDB {
    my ( $self, $hrProperties, $id ) = @_;

    my $dbItem = Common::DB::Item::Client->Lookup( client_id => $id );
    my $orchard_client = Common::DB::Item::Client->GetOrchardClient( client_id => $id );

    $hrProperties->{orchard_client} = $orchard_client->{oci} if $orchard_client;
    $self->_propertiesFromDBItem( $hrProperties, $dbItem );
}

sub _propertiesFromDBItem {
    my ( $self, $hrProperties, $dbItem ) = @_;

    # !!! There is a lot of cruft in client that we really don't need anymore.
    # !!! So I won't bother putting it in the XML
    #
    $hrProperties->{client_id}                = $dbItem->client_id;
    $hrProperties->{client_name}              = $dbItem->client_name;
    $hrProperties->{client_name_clean}        = $dbItem->client_name_clean;
    $hrProperties->{web_alias}                = $dbItem->web_alias;
    $hrProperties->{main_page}                = $dbItem->main_page;
    $hrProperties->{db_host}                  = $dbItem->db_host;
    $hrProperties->{type_mask}                = $dbItem->type_mask;
    $hrProperties->{country_code}             = $dbItem->country_code;
    $hrProperties->{secondary_market_country} = $dbItem->secondary_market_country;
    $hrProperties->{language_code}            = $dbItem->language_code;
    $hrProperties->{hfa_manufacturer_code}    = $dbItem->hfa_manufacturer_code;
    $hrProperties->{job_priority_scale}       = $dbItem->job_priority_scale;
    $hrProperties->{email}                    = $dbItem->email;
    $hrProperties->{display_name}             = $dbItem->display_name;

}

sub _propertiesFromDefaults {
    my ( $self, $hrProperties ) = @_;
}

sub _initSubs {
    my ( $self, $hrProperties ) = @_;
}

sub _initProperties {
    my ( $self, $props ) = @_;

    $self->{ClientID} = Common::FormObject::Scalar->new( value => $props->{client_id}, readOnly => 1 );
    $self->{ClientName}          = Common::FormObject::Scalar::String->new( value => $props->{client_name} );
    $self->{ClientNameClean}     = Common::FormObject::Scalar::String->new( value => $props->{client_name_clean} );
    $self->{WebAlias}            = Common::FormObject::Scalar::String->new( value => $props->{web_alias} );
    $self->{HFAManufacturerCode} = Common::FormObject::Scalar::String->new( value => $props->{hfa_manufacturer_code} );
    $self->{MainPage}            = Common::FormObject::Scalar::String->new( value => $props->{main_page} );

    $self->{TypeMask} = Common::FormObject::Scalar->new( value => $props->{type_mask} );

    $self->{ClientEmail}       = Common::FormObject::Scalar->new( value => $props->{email} );
    $self->{ClientDisplayName} = Common::FormObject::Scalar->new( value => $props->{display_name} );

    # The following array is temporary until the RSCOMMON.OrchardClient interface is finalized. (RSD-6870)
    my @orchardClients = (
        9, 16, 46, 51, 75, 118, 146, 162, 201, 203, 216, 262, 263, 284, 306,
        320, 334, 337, 350, 351, 353, 356, 358, 370, 372, 373, 377, 378, 379, 381,
        394, 399, 403, 408, 409, 411, 412, 413, 415, 416, 417, 423, 426, 427, 428,
        429, 430, 432, 433, 436, 437, 438, 439, 440, 441, 442, 443, 444, 450, 453,
        454, 460, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474,
        475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 488, 489, 490,
        491, 492, 493, 494, 496, 497, 498, 499, 500, 502, 503, 507, 509, 510, 511,
        512, 514, 516, 518, 519, 523, 524, 525, 526, 527, 529, 531, 532, 533, 534,
        535, 536, 538, 543, 547, 548, 551, 555, 565, 571, 579, 584, 580, 581, 583,
        587, 590, 591, 592, 593, 594, 595, 601, 603, 606, 607, 609, 616, 620, 621,
        623, 630, 631, 632, 633, 637, 638, 639, 640, 641, 642, 643,
        202, 288, 60, 374, 287  # test sites
    );

    if ( grep( /^$props->{client_id}$/, @orchardClients ) ) {
        $self->{OrchardClient} = Common::FormObject::Scalar->new( value => $props->{orchard_client} );
    }

    #
    # !!! If at some point we want to have 'TypeMask' exploded out so that there is a seperate XML property
    # for each client type, I recommed we create a new subclass.   That way we can have that subclass pull
    # in the ClientType table data, too, without cluttering up this base class.

    my $client_id = $props->{client_id};
    if ( $client_id && exists $Common::RSDB::CLIENT_DB{$client_id}{host_id} ) {
        $self->{DBHost} = Common::FormObject::Scalar::String->new( value => $Common::RSDB::CLIENT_DB{$client_id}{host_id} );
    } else {
        $self->{DBHost} = undef;
    }

    #$self->{DBHost} = Common::FormObject::Scalar::String->new(value => $props->{db_host});
    #
    # !!! This seems like a good thing, except that we haven't bothered to _populate_ this column
    # in the database.  Right now the DBHost data is stored in a hash in code someplace.
    # I would like to leave this class as pristine as possible, so if we don't get around to putting
    # DBHost in the database, I recommend we subclass this class to populate this XML property from
    # the hash.

    $self->{Locale} = Common::Locale->new(
        countryCode                => $props->{country_code},
        secondaryMarketCountryCode => $props->{secondary_market_country},
        languageCode               => $props->{language_code}
    ) if ( $props->{country_code} && $props->{language_code} );

    $self->{JobPriorityScale} = Common::FormObject::Scalar->new( value => $props->{job_priority_scale} );
}

sub isClientType {
    my ( $self, $type ) = @_;
    assert( $type, "ERROR - must specify a type mask" );

    my $mask = $self->TypeMask();
    return ( ( $mask & $type ) ? 1 : 0 );
}

# This STATIC class method will return the client object that matches the current client id.
#
sub Current {
    my $cache = Common::RSApp::GetRAMCache();

    if ( !$cache->{_clientObj} ) {
        my $clientID = Common::RSApp::GetClientID();
        $cache->{_clientObj} = Common::Client->new( clientID => $clientID );
    }
    return $cache->{_clientObj};
}

###
1;    #
###
