#!/usr/bin/perl

# Created on: 2014-03-11 21:06:01
# Create by:  Ivan Wills
# $Id$
# $Revision$, $HeadURL$, $Date$
# $Revision$, $Source$, $Date$

use strict;
use warnings;
use Getopt::Long;
use Pod::Usage ();
use Data::Dumper qw/Dumper/;
use English qw/ -no_match_vars /;
use Git::Workflow;

our $VERSION = 0.6;
my ($name)   = $PROGRAM_NAME =~ m{^.*/(.*?)$}mxs;
my $workflow = Git::Workflow->new;

my %option = (
    url     => $workflow->config('jira.url'),
    verbose => 0,
    man     => 0,
    help    => 0,
    VERSION => 0,
);

if ( !@ARGV ) {
    Pod::Usage::pod2usage( -verbose => 1 );
}

main();
exit 0;

sub main {


    Getopt::Long::Configure('bundling');
    GetOptions(
        \%option,
        'all|a',
        'list|l',
        'remote|r',
        'quiet|q!',
        'url|u=s',
        'user|U=s',
        'pass|password|P=s',
        'verbose|v+',
        'man',
        'help',
        'VERSION!',
    ) or Pod::Usage::pod2usage(2);

    if ( $option{'VERSION'} ) {
        print "$name Version = $VERSION\n";
        exit 1;
    }
    elsif ( $option{'man'} ) {
        Pod::Usage::pod2usage( -verbose => 2 );
    }
    elsif ( $option{'help'} ) {
        Pod::Usage::pod2usage( -verbose => 1 );
    }


    # do stuff here
    my $jira_re = my $jira = shift @ARGV;
    $jira_re =~ s/[-_]/[-_]/;
    $jira_re = lc $jira_re;

    # check local branches first
    my @branch = grep {/^(\w+_)?$jira_re(?:\D|$)/} $workflow->branches();

    if (@branch && !$option{remote}) {
        my $branch = which_branch(@branch);
        system qw/git checkout/, $branch;
    }
    else {
        # check if there is a remote branch
        my (@remote_branch) = grep {/^origin\/(\w+_)?$jira_re/} $workflow->branches('remote');
        if (@remote_branch) {
            my $remote_branch = which_branch(@remote_branch);
            my $branch = $remote_branch;
            $branch =~ s{^origin/}{};
            system qw/git checkout -b/, $branch, '--track', $remote_branch;
        }
        elsif (!$option{quiet}) {
            if ( $option{url} && eval { require JIRA::REST } ) {
                $jira =~ s/_/-/;
                $jira = uc $jira;
                my $jira_rest = JIRA::REST->new($option{url}, $option{user}, $option{pass});
                my $issue     = eval { $jira_rest->GET("/issue/$jira") };
                my $branch    = lc "$jira $issue->{fields}{summary}";
                $branch =~ s/[ !?-]+/_/gxms;

                warn "No branch found for $jira!\n";
                warn "Create with one of the following:\n";
                warn "git feature $branch\n";
            }
            else {
                # suggest how to construct the branch
                warn "No branch for jira $jira exists!\n";
                warn "Create with one of the following:\n";
                warn "git feature $jira\n";
            }
        }
    }

    return;
}

sub which_branch {
    my @branches = map {/(.*)$/} @_;

    if ($option{list}) {
        print +( join "\n", @branches ), "\n";
        exit 0;
    }
    return $branches[0] if @branches == 1;

    my $count = 0;
    print {*STDERR} "Which branch:\n\t";
    print {*STDERR} join "", map { ++$count . ". $_\n\t" } @branches;
    print {*STDERR} "\n[1..$count] : ";
    my $ans = <STDIN>;
    chomp $ans;
    $ans--;
    die "Bad answer!\n" if !$branches[$ans];

    return $branches[$ans];
}

__DATA__

=head1 NAME

git-jira - Checkout any branch mentioning the passed Jira

=head1 VERSION

This documentation refers to git-jira version 0.6

=head1 SYNOPSIS

   git-jira [option] JIRAID

 OPTIONS:
  JIRAID            A Jira format id
  -r --remote       Look in remote branches for the Jira branch
  -a --all          Look everywhere?
  -u --url[=]URL    Use URL as the JIRA instance for looking up summaries.

  -v --verbose      Show more detailed option
     --VERSION      Prints the version information
     --help         Prints this help information
     --man          Prints the full documentation for git-Jira

=head1 DESCRIPTION

Finds any branch containing the passed Jira issue id and switches to that
branch. If none is found then it suggests creating the branch using
L<git-feature>. If L<JIRA::REST> is installed the suggestion will use the
JIRA summary as part of the name.

=head1 SUBROUTINES/METHODS

=head1 DIAGNOSTICS

=head1 CONFIGURATION AND ENVIRONMENT

Defaults for this script can be set thought C<git config>

 jira.url       Specifiys the URL for the JIRA instance being used.

You can set these values either by editing the repository local C<.git/config>
file or C<~/.gitconfig> or use the C<git config> command

 # eg Setting the local value (ie only the current repository)
    git config jira.url https://jira.example.com/

 # eg Setting the global value
    git config --global jira.url https://jira.example.com/

=head1 DEPENDENCIES

=head1 INCOMPATIBILITIES

=head1 BUGS AND LIMITATIONS

There are no known bugs in this module.

Please report problems to Ivan Wills (ivan.wills@gmail.com).

Patches are welcome.

=head1 AUTHOR

Ivan Wills - (ivan.wills@gmail.com)

=head1 LICENSE AND COPYRIGHT

Copyright (c) 2014 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077).
All rights reserved.

This module is free software; you can redistribute it and/or modify it under
the same terms as Perl itself. See L<perlartistic>.  This program is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

=cut