package App::bif::update::project;
use strict;
use warnings;
use Bif::Mo;
use DBIx::ThinSQL qw/sq qv/;
use IO::Prompt::Tiny qw/prompt/;
use Time::Duration qw/concise duration/;

our $VERSION = '0.1.5_3';
extends 'App::bif';

sub run {
    my $self = shift;
    my $opts = $self->opts;
    my $dbw  = $self->dbw;

    $dbw->txn(
        sub {
            my $info =
              $self->get_project( $opts->{id} ? $opts->{id} : $opts->{path} );

            $self->start_work(
                id            => $info->{id},
                start         => time,
                start_comment => "update project",
                billable      => 1,
                save          => 1,
            );

            my ( $status_ids, $invalid );
            if ( $opts->{status} ) {

                ( $status_ids, $invalid ) =
                  $dbw->status_ids( $info->{id}, 'project', $opts->{status} );

                return $self->err( 'InvalidStatus',
                    'unknown status(s): ' . join( ', ', @$invalid ) )
                  if @$invalid;
            }

            if ( $opts->{reply} ) {
                my $uinfo =
                  $self->get_change( $opts->{reply}, $info->{first_change_id} );
                $opts->{parent_uid} = $uinfo->{id};
            }
            else {
                $opts->{parent_uid} = $info->{first_change_id};
            }

            $opts->{message} ||=
              $self->prompt_edit( opts => $self, id => $info->{id} );

            $opts->{change_id} =
              $self->new_change( parent_id => $opts->{parent_uid}, );

            $self->stop_work(
                id      => $opts->{id},
                stop    => time,
                restore => 1,
            );

            $dbw->xdo(
                with => 'w',
                as   => sq(
                    select => 'sum(wb.stop - wb.start) AS delta',
                    from   => 'work_buffers wb',
                    where  => {
                        'wb.topic_id'  => $info->{id},
                        'wb.billable'  => 1,
                        'wb.change_id' => undef,
                    },
                    group_by => 'null',
                    having   => 'delta > 0',
                ),
                insert_into => [
                    'func_update_project', qw/id change_id
                      work_delta title project_status_id/
                ],
                select => [
                    qv( $info->{id} ),
                    qv( $opts->{change_id} ),
                    'w.delta',
                    qv( $opts->{title} ),
                    qv( $status_ids->[0] ),
                ],

                from      => '(select 1)',
                left_join => 'w',
            );

            $dbw->xdo(
                update => 'work_buffers',
                set    => { change_id => $opts->{change_id} },
                where  => {
                    topic_id  => $info->{id},
                    billable  => 1,
                    change_id => undef,
                    'stop !'  => undef,
                },
            );

            my $path = $dbw->xval(
                select => 'path',
                from   => 'topic_path tp',
                where  => { 'tp.id' => $opts->{id} },
            );

            $self->end_change(
                id                => $opts->{change_id},
                action_format     => "update project $path (%s)",
                action_topic_id_1 => $info->{id},
                message           => $opts->{message},
            );

        }
    );

    return $self->ok('ChangeProject');
}

1;
__END__

=head1 NAME

=for bif-doc #modify

bif-update-project - update a project

=head1 VERSION

0.1.5_3 (2015-06-30)

=head1 SYNOPSIS

    bif update project ID [STATUS] [OPTIONS...]

=head1 DESCRIPTION

Add a comment to a project, possibly setting a new status at the same
time. Valid values for a project's status depend on the project it is
associated with. The list of valid status for a project can be found
using L<bif-list-status>(1).

=head1 ARGUMENTS

=over

=item PATH

A project PATH. Required.

=item STATUS

The new status for the topic.

=back

=head1 OPTIONS

=over

=item --title, -t

The new title for the topic.

=item --message, -m

The message describing this issue in detail. If this option is not used
an editor will be invoked.

=back

=head1 SEE ALSO

L<bif>(1)

=head1 AUTHOR

Mark Lawrence E<lt>nomad@null.netE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright 2013-2015 Mark Lawrence <nomad@null.net>

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

