package App::bif::log;
use strict;
use warnings;
use feature 'state';
use locale;
use parent 'App::bif::Context';
use utf8;
use Text::Autoformat qw/autoformat/;

our $VERSION = '0.1.0_28';

sub init {
    my $self = shift;
    $self->{_now} = time;
    $self->colours(qw/bold yellow white dark reset/);
}

sub run {
    my $self = __PACKAGE__->new(shift);
    my $db   = $self->db();

    if ( $self->{id} ) {
        my $info  = $self->get_topic( $self->{id} );
        my $class = "App::bif::log::$info->{kind}";

        if ( eval "require $class" ) {
            $self->{path} = delete $self->{id}
              if ( $info->{kind} eq 'project' );

            return $class->can('run')->($self);
        }
        die $@ if $@;
        return $self->err( 'LogUnimplemented',
            'cannnot log type: ' . $info->{kind} );
    }

    $self->{order} = 'time';
    require App::bif::log::repo;
    return App::bif::log::repo::run($self);
}

sub reformat {
    my $self  = shift;
    my $text  = shift;
    my $depth = shift || 0;

    $depth-- if $depth;

    my $left   = 1 + 4 * $depth;
    my $indent = '    ' x $depth;

    my @result;

    foreach my $para ( split /\n\n/, $text ) {
        if ( $para =~ m/^[^\s]/ ) {
            push( @result, autoformat( $para, { left => $left } ) );
        }
        else {
            $para =~ s/^/$indent/gm;
            push( @result, $para, "\n\n" );
        }
    }

    return @result;
}

my $title;
my $path;

sub log_item {
    my $self = shift;
    my $row  = shift;
    my $type = shift;

    $title = $row->{title};
    $path  = $row->{path};

    ( my $id = $row->{change_id} ) =~
      s/(.+)\./$self->{_colours}->{yellow}$1$self->{_colours}->{dark}\./;
    my @data = (
        $self->header(
            $self->{_colours}->{yellow} . $row->{change_id},
            $self->{_colours}->{yellow} . $row->{action},
            $row->{change_uuid}
        ),
        $self->header( 'From', $row->{author}, $row->{email} ),
    );

    push( @data, $self->header( 'To', $row->{path} ) ) if $row->{path};
    push( @data,
        $self->header( 'When', $self->ago( $row->{mtime}, $row->{mtimetz} ) ) );

    if ( $row->{status} ) {
        push(
            @data,
            $self->header(
                'Subject', "[$row->{path}][$row->{status}] $row->{title}"
            )
        );
    }
    else {
        push( @data,
            $self->header( 'Subject', "[$row->{path}] $row->{title}" ) );
    }

    foreach my $field (@_) {
        next unless defined $field->[1];
        push( @data, $self->header(@$field) );
    }

    print $self->render_table( 'l  l', undef, \@data ) . "\n";
    print $self->reformat( $row->{message} ), "\n";

    return;
}

sub log_comment {
    my $self = shift;
    my $row  = shift;
    my @data;

    push(
        @data,
        $self->header(
            $self->{_colours}->{dark}
              . $self->{_colours}->{yellow}
              . $row->{change_id},
            $self->{_colours}->{dark}
              . $self->{_colours}->{yellow}
              . $row->{action},
            $row->{change_uuid}
        ),
        $self->header( 'From', $row->{author}, $row->{email} ),
    );

    $path = $row->{path} if $row->{path};
    push( @data, $self->header( 'To', $path ) ) if $path;
    push( @data,
        $self->header( 'When', $self->ago( $row->{mtime}, $row->{mtimetz} ) ) );

    if ( $row->{title} ) {
        $title = $row->{title} if $row->{title};
        push( @data, $self->header( 'Subject', "$title" ) );
    }
    elsif ( $row->{status} ) {
        push( @data, $self->header( 'Subject', "[$row->{status}] $title" ) );
    }
    else {
        push( @data, $self->header( 'Subject', "↪ $title" ) );
    }

    foreach my $field (@_) {
        next unless defined $field->[1];
        push( @data, $self->header(@$field) );
    }

    print $self->render_table( 'l  l', undef, \@data,
        4 * ( $row->{depth} - 1 ) )
      . "\n";

    if ( $row->{push_to} ) {
        print "[Pushed to " . $row->{push_to} . "]\n\n\n";
    }
    else {
        print $self->reformat( $row->{message}, $row->{depth} ), "\n";
    }
}

1;
__END__

=head1 NAME

bif-log - review the repository or topic history

=head1 VERSION

0.1.0_28 (2014-09-23)

=head1 SYNOPSIS

    bif log [ITEM] [OPTIONS...]

=head1 DESCRIPTION

The C<bif log> command displays repository history. Without any
arguments it is equivalent to C<bif log repo --order time>, which
displays the history of changes in the current repository in reverse
chronological order.

=head1 ARGUMENTS & OPTIONS

=over

=item ITEM

A topic kind. As a shortcut, if ITEM is a topic ID or a project PATH
then the ITEM kind will be looked up and the appropriate sub-command
run.

=back

=head1 SEE ALSO

L<bif>(1)

=head1 AUTHOR

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

=head1 COPYRIGHT AND LICENSE

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