#!/usr/bin/perl -w
use strict;

use Readonly;

use IO::Prompt;
use IO::All;
use File::Spec::Functions;

Readonly my $CONF_DIR => catfile($ENV{'HOME'}, '.sql-profiles');

my $X = {'ARGV' => []};

read_profiles();

if ($#ARGV > -1) {
    find_profile_for_user();
}

if (!defined($X->{'profile'})) {
    $X->{'profile'} = prompt -menu => $X->{'profiles'};
}

my $profile = $X->{'profile'};

my @all_options = ();
for my $option (grep { $_ ne 'psql' } keys %{$X->{'options'}->{$profile}}) {
    unshift @{$X->{'ARGV'}}, $X->{'options'}->{$profile}->{$option};
    unshift @{$X->{'ARGV'}}, "-$option";
}
my $psql = $X->{'options'}->{$profile}->{'psql'} || 'psql';

exec $psql, @{$X->{'ARGV'}};

exit;

sub find_profile_for_user {
    my $profile = $ARGV[0];
    my @possible = @{$X->{'profiles'}};
    my @matching = grep { /^\Q$profile\E/ } @possible;
    if (scalar @matching == 1) {
        $X->{'profile'} = $matching[0];
        shift @ARGV;
    }
    $X->{'ARGV'} = [ @ARGV ];
    @ARGV = ();
    return;
}

sub read_profiles {
    my $dir = io($CONF_DIR);
    $dir->filter(
        sub { $_->filename =~ m/\.conf$/ }
    );
    my @files = $dir->all_files();

    for my $file (sort { $a->filename cmp $b->filename } @files) {
        my $file_name = $file->filename;
        my @content = $file->slurp;

        my $code = $file_name;
        $code =~ s/\.conf$//;

        push @{$X->{'profiles'}}, $code;
        
        $X->{'options'}->{$code}->{'psql'} = 'psql';

        for my $line (@content) {
            if ($line =~ /^(?:user|database|host|port)\s*=\s*(\S+)\s*$/i) {
                $X->{'options'}->{$code}->{lc substr $line, 0, 1} = $1;
            }
            if ($line =~ /^psql\s*=\s*(\S+)\s*$/i) {
                $X->{'options'}->{$code}->{'psql'} = $1;
            }
        }
        if ($X->{'options'}->{$code}->{'u'}) {
            $X->{'options'}->{$code}->{'U'} = $X->{'options'}->{$code}->{'u'};
            delete $X->{'options'}->{$code}->{'u'};
        }
    }
    return;
}

