package App::bif::show::project;
use strict;
use warnings;
use Bif::Mo;

our $VERSION = '0.1.5_7';
extends 'App::bif::show';

sub run {
    my $self = shift;
    my $opts = $self->opts;
    my $db   = $self->db;
    my $info = $self->get_project( $opts->{id} ? $opts->{id} : $opts->{path} );
    my $now  = $self->now;

    my @data;

    DBIx::ThinSQL->import(qw/sum case coalesce concat qv/);

    my $ref = $db->xhashref(
        select => [
            'nodes.id',
            'substr(nodes.uuid,1,8) as uuid',
            'nodes.path',
            'projects.title',
            'nodes.ctime AS ctime',
            'nodes.ctimetz AS ctimetz',
            'nodes.ctimetzhm AS ctimetzhm',
            "$now - nodes.ctime AS ctime_age",
            'nodes.mtime AS mtime',
            'nodes.mtimetz AS mtimetz',
            'nodes.mtimetzhm AS mtimetzhm',
            "$now - nodes.mtime AS mtime_age",
            'changes.author',
            'changes.author_contact AS contact',
            'changes.message',
            'project_status.status',
            'project_status.status',
            'projects.local',
            'hn.name AS hub',
            'hn.uuid AS hub_uuid',
            'h.location',
        ],
        from       => 'projects',
        inner_join => 'nodes',
        on         => 'nodes.id = projects.id',
        inner_join => 'changes',
        on         => 'changes.id = nodes.first_change_id',
        inner_join => 'project_status',
        on         => 'project_status.id = projects.project_status_id',
        left_join  => 'nodes hn',
        on         => 'hn.id = projects.default_hub_id',
        left_join  => 'hubs h',
        on         => 'h.id = projects.default_hub_id',
        where      => { 'projects.id' => $info->{id} },
    );

    push( @data, $self->header( '  Path', $ref->{path}, $ref->{uuid} ), );
    push( @data, $self->header( '  Hub',  $ref->{hub},  $ref->{location} ), )
      if $ref->{hub};

    if ( $opts->{full} ) {
        push( @data,
            $self->header( '  Creator', $ref->{author}, $ref->{contact} ),
            $self->header( '  Created', $self->ctime_ago($ref) ),
        );
    }

    my @phases = $db->xarrayrefs(
        select => [
            case (
                when => { status => $ref->{status} },
                then => 'UPPER(status)',
                else => 'status',
            )->as('status'),
        ],
        from     => 'project_status',
        where    => { project_id => $info->{id} },
        order_by => 'rank',
    );

    push( @data,
        $self->header( '  Phases', join( ', ', map { $_->[0] } @phases ) ),
    );

    if ( $ref->{local} ) {

        # TODO: need to use actual status names here
        my $sth = $db->xprepare(
            select => [
                'ts.tkind AS tkind',
                coalesce( sum( { 'ts.status' => 'open' } ),    0 )->as('open'),
                coalesce( sum( { 'ts.status' => 'stalled' } ), 0 )
                  ->as('stalled'),
                coalesce( sum( { 'ts.status' => 'closed' } ), 0 )->as('closed'),
                coalesce( sum( { 'ts.status' => 'ignored' } ), 0 )
                  ->as('ignored'),
            ],
            from       => 'topic_status ts',
            inner_join => 'topics t',
            on         => 't.topic_status_id = ts.id',
            where      => { 'ts.project_id' => $info->{id} },
            group_by   => 'ts.tkind',
        );

        $sth->execute;

        my $closed;
        my $total;

        while ( my $row = $sth->hashref ) {
            push(
                @data,
                $self->header(
                    '  ' . ucfirst( $row->{tkind} ),
                    "$row->{open} open, "
                      . "$row->{stalled} stalled, "
                      . "$row->{closed} closed, "
                      . "$row->{ignored} ignored"
                ),
            );
            $closed += $row->{closed};
            $total  += $row->{open} + $row->{stalled} + $row->{closed};
        }

        my $progress = $total ? int( ( $closed / $total ) * 100 ) : 0;

        push( @data,
            $self->header( '  Progress', $progress . '%' ),
            $self->header( '  Updated',  $self->mtime_ago($ref) ) );
    }

    if ( $opts->{full} ) {
        require Text::Autoformat;
        push(
            @data,
            $self->header(
                'Description',
                Text::Autoformat::autoformat(
                    $ref->{message},
                    {
                        right => 60,
                        all   => 1
                    }
                )
            ),
        );
    }
    $self->start_pager;
    print $self->render_table( 'l  l', [ 'Project', $ref->{title} ], \@data,
        1 );

    print "\n";
    $self->dispatch( 'App::bif::log::project',
        opts => { path => $info->{path} } )
      if $opts->{log};

    return $self->ok( 'ShowProject', \@data );
}

1;
__END__

=head1 NAME

=for bif-doc #show

bif-show-project - display a project's current status

=head1 VERSION

0.1.5_7 (2015-11-25)

=head1 SYNOPSIS

    bif show project PATH [OPTIONS...]

=head1 DESCRIPTION

The B<bif-show-project> command displays a summary of a project's
current status.

    bif show project todo

    # Project:     title fdslijfdslijjfds                 
    #   Path:      todo <529ccc29>                        
    #   Hub:       hub </home/mark/src/bif/hub>           
    #   Phases:    define, plan, RUN, eval, closed        
    #   Progress:  0%                                     
    #   Tasks:     1 open, 0 stalled, 0 closed, 0 ignored 
    #   Issues:    1 open, 0 stalled, 0 closed, 0 ignored 
    #   Updated:   3 days ago <Sun 2014-05-04 21:44 +0200>

=head1 ARGUMENTS & OPTIONS

=over

=item PATH

A project path of the form PATH[@HUB]. Required.

=item --full, -f

Display a more verbose version of the current status.

=item --uuid, -U

Lookup the node using ID as a UUID string instead of a node integer.

=back

=head1 SEE ALSO

L<bif>(1)

=head1 AUTHOR

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

=head1 COPYRIGHT AND LICENSE

Copyright 2014-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.

