#!/usr/bin/env perl

use common::sense;
use Getopt::Long ();
use Pod::Usage ();
use Log::Log4perl ();
use Log::Log4perl::Appender::Lim::CLI ();
$Log::Log4perl::JOIN_MSG_ARRAY_CHAR = '';

use AnyEvent ();
if (AnyEvent->VERSION < 6.01) {
    # Try and force detection of modules for old AnyEvents
    foreach (qw(EV Event Glib EventLib POE)) {
        eval "use $_ ();";
        unless ($@) {
            last;
        }
    }
    AnyEvent::detect;
}

use Lim ();
use Lim::CLI ();
use Lim::RPC::TLS ();

my $help = 0;
my $conf;
my $host;
my $port;
my $log4perl;
my @options;

Getopt::Long::GetOptions(
    'help|?' => \$help,
    'conf:s' => \$conf,
    'host:s' => \$host,
    'port:i' => \$port,
    'log4perl:s' => \$log4perl,
    'option:s' => \@options
) or Pod::Usage::pod2usage(2);
Pod::Usage::pod2usage(1) if $help;

if (defined $log4perl and -f $log4perl) {
    Log::Log4perl->init($log4perl);
}
else {
    Log::Log4perl->init( \q(
    log4perl.logger                   = DEBUG, Screen, LimCLI
    log4perl.appender.Screen          = Log::Log4perl::Appender::Screen
    log4perl.appender.Screen.stderr   = 1
    log4perl.appender.Screen.layout   = Log::Log4perl::Layout::PatternLayout
    log4perl.appender.Screen.layout.ConversionPattern = %d %F [%L] %p: %m%n
    
    log4perl.appender.LimCLI          = Log::Log4perl::Appender::Lim::CLI
    log4perl.appender.LimCLI.stderr   = 1
    log4perl.appender.LimCLI.layout   = Log::Log4perl::Layout::PatternLayout
    log4perl.appender.LimCLI.layout.ConversionPattern = %d %F [%L] %p: %m%n
    ) );
}

Lim::LoadConfig('/etc/lim/cli.yaml');
Lim::LoadConfigDirectory('/etc/lim/cli.d');

if (defined $conf) {
    unless (-r $conf and Lim::LoadConfig($conf)) {
        print STDERR 'Unable to read configuration file: ', $conf, "\n";
        exit(1);
    }
    Lim::Config->{cli}->{config_file} = $conf;
}
else {
    Lim::LoadConfig(Lim::Config->{cli}->{config_file});
}

Lim::ParseOptions(@options);
Lim::UpdateConfig;

if (defined $host) {
    Lim::Config->{host} = $host;
}
else {
    Lim::Config->{host} = Lim::Config->{cli}->{host};
}

if (defined $port) {
    Lim::Config->{port} = $port;
}
else {
    Lim::Config->{port} = Lim::Config->{cli}->{port};
}

my $cv = AnyEvent->condvar;
my @watchers;
my $cli;

push(@watchers,
    AnyEvent->signal(signal => "HUP", cb => sub {
    }),
    AnyEvent->signal(signal => "PIPE", cb => sub {
    }),
    AnyEvent->signal(signal => "INT", cb => sub {
        if (defined $cli) {
            $cli->clear_line;
        }
        else {
            $cv->send;
        }
    }),
    AnyEvent->signal(signal => "QUIT", cb => sub {
        $cv->send;
    }),
    AnyEvent->signal(signal => "TERM", cb => sub {
        $cv->send;
    }),
);

$cli = Lim::CLI->new(
    on_quit => sub {
        $cv->send;
    });

if (defined $cli) {
    push(@watchers, $cli);
    $cv->recv;
}

@watchers = ();

__END__

=head1 NAME

lim-cli - Lim CLI Interface

=head1 SYNOPSIS

lim-cli [options]

=head1 OPTIONS

=over 8

=item B<--conf <file>>

Specify the configuration file to use (default ~/.limrc).

=item B<--option <name>=<value>>

Specify configuration on the command line, these settings overrides settings in
configuration files. Syntax <name>=<value> will set <name> to <value> and
<name>[]=<value> will treat <name> as an multi option array and append <value>.
Option subgroups are seperated by . (for example log.obj_debug=0). 

=item B<--host <ip>>

Specify the host/IP to connect to (default localhost).

=item B<--port <port>>

Specify the port to listen on (default 5353).

=item B<--log4perl <file>>

Specify a Log::Log4perl configure file (default output to cli or stderr).

=item B<--help>

Print a brief help message and exits.

=item B<--man>

Prints the manual page and exits.

=back

=head1 DESCRIPTION

...

=cut

