package Common::DB::Connect;

use strict;
use warnings;

use DBI;
use Sys::Hostname;

use lib '/app/tools/common/lib';
use Common::YamlConfig;

sub dsn {
    my $self = shift;
    my $conf = shift;

    my $config = Common::YamlConfig::get_config(__PACKAGE__);
    my $dsncnf = $config->dbhost->{$conf};
    if ( not defined $dsncnf ) {
        my $localcnf = "$ENV{'HOME'}/.dbconn.yml";
        if ( -e $localcnf ) {
            $config = Common::YamlConfig::get_config_from_file($localcnf);
            $dsncnf = $config->dbhost->{$conf};
        }
    }
    die "$conf is not in " . $config->file if not defined $dsncnf;

    my $host = defined $dsncnf->{'host'}   ? $dsncnf->{'host'}   : $config->default_host;
    my $port = defined $dsncnf->{'port'}   ? $dsncnf->{'port'}   : $config->default_port;
    my $drvr = defined $dsncnf->{'driver'} ? $dsncnf->{'driver'} : $config->default_driver;
    my $user = defined $dsncnf->{'user'}   ? $dsncnf->{'user'}   : $config->default_user;
    my $pass = defined $dsncnf->{'pass'}   ? $dsncnf->{'pass'}   : $config->default_pass;
    my $scma = defined $dsncnf->{'schema'} ? $dsncnf->{'schema'} : '';

    $host = '127.0.0.1' if $host eq Sys::Hostname::hostname;

    my $dsn;
    my $opts;
    if ( $drvr eq 'dbi:Pg' ) {
        $dsn  = "${drvr}:dbname=${scma};host=$host;port=$port;";
        $opts = { 'PrintError' => 0, 'RaiseError' => 0 };
    } else {
        $dsn = "${drvr}:dbname=${scma}:host=$host:port=$port;mysql_skip_secure_auth=1;mysql_local_infile=1";
    }

    [ $dsn, $user, $pass, $opts ];

}

sub connect {
    my $self = shift;
    my $host = shift;
    my $dsn  = Common::DB::Connect->dsn($host);
    my $dbh;
    my $try = 0;
    while ( $try < 3 ) {
        $dbh = DBI->connect( @{$dsn} );
        if ( defined $DBI::errstr ) {
            my $err = $DBI::errstr;
            if ( $err =~ m/.*closed unexpectedly.*/is ) {
                sleep 5;
            } else {
                die "[$DBI::err] conn: $err";
            }
            $try++;
        } else {
            $try = 4;
        }
    }
    $dbh;
}

sub databases {
    my $self = shift;
    my $host = shift;
    my $dsn  = Common::DB::Connect->dsn($host);
    my $dbh  = DBI->connect( @{$dsn} ) || die "Err: $DBI::err - Conn: $DBI::errstr";

    my $dbs;
    my $rows = $dbh->selectcol_arrayref('show databases');
    foreach my $row ( @{$rows} ) {
        if ( $row =~ m/^C\_|^RSCO/ ) {
            push @{ $dbs->{'rps'} }, $row;
        } elsif ( $row =~ m/^BP\_/i ) {
            push @{ $dbs->{'dtmv'} }, $row;
        } else {
            push @{ $dbs->{'misc'} }, $row;
        }
        push @{ $dbs->{'all'} }, $row;
    }

    ( $dbh, $dbs );
}

1;
