#!/usr/bin/perl

use strict;
use warnings;
use LATMOS::Accounts;
use LATMOS::Accounts::Utils;
use Getopt::Long;
use Pod::Usage;

=head1 NAME

    la-sql-valid-request - Validate changes request

=head1 SYNOPSIS

    la-sql-valid-request [options] obj_id

=cut

GetOptions(
    'c|config=s' => \my $config,
    'b|base=s'   => \my $base,
    'comment=s'  => \my $comment,
    'help'       => sub { pod2usage(0) },
) or pod2usage();

=head1 OPTIONS

=over 4

=item -c|--config configdir

Use this configuration directory instead of the default one.

=item -b|--base basename

Query this specific base instead of the default one.

=back

=cut

if (!$ARGV[0]) {
    warn "You must specify 'obj_id', aborting\n";
    pod2usage();
}

my $LA = LATMOS::Accounts->new($config, noacl => 1);
my $labase = $LA->base($base);
$labase && $labase->load or die "Cannot load base";
$labase->wexported(1);

my $datarequest = $labase->get_datarequest($ARGV[0]) or do {
    die "Data request $ARGV[0] not found\n";
};

sub input_from_handle {
    my ($fh) = @_;
    my %attr = LATMOS::Accounts::Utils::parse_obj_file($fh);
    my $res = $datarequest->apply_to_object($comment, %attr);
    if($res) {
        print "Changes applied\n";
        $LA->call_batch_sync;
    }
    return
    $res ? 1 : 0;
}

sub create_object {
    my ($fh) = @_;

    my %attrs = LATMOS::Accounts::Utils::parse_obj_file($fh);

    my %newvalues = $datarequest->_prepare_attrs(%attrs);

    # this mean creating a new object (woot)
    my $ochelper = $labase->ochelper($datarequest->otype);
    my ($status, $info);

    foreach my $attr (keys %newvalues) {
        $info->{contents}{$attr} = $newvalues{$attr};
    }
    while (1) {
        ($status, $info) = $ochelper->step($info);
        if ($status eq 'CREATED') {
            $datarequest->_register_applied($comment);
            printf 
                "Object %s %s created\n",
                $datarequest->otype,
                $info->{name}{content}; 
            $labase->commit;
            return 1;
        } elsif ($status eq 'ERROR') {
            die "Error when creating object\n";
        } elsif ($status eq 'NEEDINFO') {
            LATMOS::Accounts::Utils::dump_read_temp_file(
                sub {
                    my ($fh) = @_;
                    if ($info->{name}{ask}) {
                        printf $fh "name: %s\n", $info->{name}{content};
                    }
                    foreach (@{ $info->{ask} }) {
                        printf $fh "%s: %s\n", $_, $info->{contents}{$_} || '';
                    }
                    return 1;
                },
                sub {
                    my ($fh) = @_;
                    my %attrs = LATMOS::Accounts::Utils::parse_obj_file($fh);
                    if ($info->{name}{ask}) {
                        $info->{name}{content} = $attrs{name};
                        delete($attrs{name});
                    }
                    foreach (keys %attrs) {
                        $info->{contents}{$_} = $attrs{$_};
                    }
                    return 1;
                },
            );
            next;
        }
    }
}

exit(
    ! LATMOS::Accounts::Utils::dump_read_temp_file(
        sub {
            my ($fh) = @_;
            if ($datarequest->accreq->get_attributes('requireObject')) {
                printf $fh "# Modify Object %s/%s\n",
                $datarequest->otype,
                $datarequest->oobject->id;
            }
            my %vals = $datarequest->get_values;
            foreach my $attr ($datarequest->attributes) {
                foreach (ref $vals{$attr} ? @{ $vals{$attr} } :
                    $vals{$attr}) {
                    printf $fh "$attr: %s\n", $_ || '';
                }
            }
            return 1;
        },
        sub {
            my ($fh) = @_;
            if ($datarequest->is_for_new_object) {
                return create_object($fh);
            } else {
                return input_from_handle($fh);
            }
        }
    )
);
