package LATMOS::Accounts::Cli::Context;

# $Id: Cli.pm 2145 2018-08-29 18:15:46Z nanardon $

use strict;
use warnings;
use Moose;
use LATMOS::Accounts::Log;
use LATMOS::Accounts::Utils;
use Term::ReadLine;
use Text::ParseWords;
use Getopt::Long;
use YAML;
use utf8;
use open qw( :std :utf8 );

=head1 NAME

LATMOS::Accounts::Cli - Command line interface functions

=head1 DESCRIPTION

This module handle envirronment and functons for L<la-cli> tools.

=cut

{
    open (my $fh, "/dev/tty" )
        or eval 'sub Term::ReadLine::findConsole { ("&STDIN", "&STDERR") }';
    die $@ if $@;
    close ($fh);
}

has Term => ( is => 'ro', isa => 'Term::ReadLine' );
has TransMode => ( is => 'rw', isa => 'Bool', default => 0 );
has TransStarted => ( is => 'rw', isa => 'Bool', default => 0 );
has base => ( is => 'ro' );
has La => ( is => 'ro' );
has Out => ( is => 'ro' );
has TempOut => ( is => 'rw' );
has Interractive => ( is => 'rw', isa => 'Bool', default => 1 );
has Preferences => ( is => 'rw', default => sub { {} } );

=head1 FUNCTIONS

=head2 new ($env, $labase)

Create an envirronment object.

C<$env> is functions descriptions.

=cut

around BUILDARGS => sub {
    my $orig = shift;
    my $class = shift;

    my $term = Term::ReadLine->new('LA CLI', \*STDIN, \*STDOUT );
    binmode($term->IN, ':utf8');
    $term->MinLine(99999);
    my $OUT = \*STDOUT;

    return $class->$orig( Out => $OUT, Term => $term, @_ );

};

sub _historyFile { "$ENV{HOME}/.lacli_history" }

sub ReadHistory {
    my ( $self ) = @_;
    $self->Term->ReadHistory( _historyFile() );
}

sub WriteHistory {
    my ( $self ) = @_;
    $self->Term->WriteHistory( _historyFile() );
}

sub _preferenceFile { "$ENV{HOME}/.lacli_preference" }

sub ReadPreferences {
    my ( $self ) = @_;

    if (-f _preferenceFile() ) {
        $self->Preferences( YAML::LoadFile( _preferenceFile() ) );
    }
    
    $self->ApplySetting();
}

sub WritePreferences {
    my ( $self ) = @_;

    YAML::DumpFile( _preferenceFile(), $self->Preferences() );
}

sub DefaultSetting {
    my ( $self, $setting ) = @_;

    my $defaults = {
        'historysize' => 1000,
    };
    if ($setting) {
        return $defaults->{ $setting };
    } else {
        return sort keys %{ $defaults };
    }
}

sub ApplySetting {
    my ( $self ) = @_;

    $self->Term->StifleHistory( $self->Setting('historysize') );
}

sub Setting {
    my ( $self, $setting, $value ) = @_;

    my $oldvalue = defined($self->Preferences->{settings}{ $setting })
        ? $self->Preferences->{settings}{ $setting } : $self->DefaultSetting( $setting );

    if (defined($value)) {
        if ($value eq 'default') {
            delete($self->Preferences->{settings}{ $setting });
        } else {
            $self->Preferences->{settings}{ $setting } = $value;
        }

        $self->ApplySetting();
    }

    return ($oldvalue);
}

=head2 print

=cut

sub print {
    my ( $self, @args ) = @_;
    my $out = $self->TempOut || $self->Out;

    print $out @args;
}

=head2 printf

=cut

sub printf {
    my ( $self, $str, @args ) = @_;
    my $out = $self->TempOut || $self->Out;

    printf $out $str, @args;
}

=head2 commit

Call commit to base unelss in transaction mode

=cut

sub commit {
    my ($self) = @_;
    if ($self->TransMode || $self->TransStarted) {
        $self->TransStarted(1);
    } else {
        $self->_commit;
    }
}

sub _commit {
    my ($self) = @_;
    $self->base->commit;
    $self->TransStarted(0);
}

=head2 rollback

Perform rollback unless in transaction mode

=cut

sub rollback {
    my ($self) = @_;
    if ($self->TransMode) {
        $self->print("All pending changes get rollback\n");
    }
    if (!$self->TransStarted) {
        $self->_rollback;
    }
}

sub _rollback {
    my ($self) = @_;
    $self->base->rollback;
    $self->TransStarted(0);
}

1;

__END__

=head1 SEE ALSO

L<LATMOS::Accounts>

=head1 AUTHOR

Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2008, 2009, 2010, 2011, 2012 CNRS SA/CETP/LATMOS

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.10.0 or,
at your option, any later version of Perl 5 you may have available.

=cut
