package App::gh::Command::Pullreq::Send;
use base qw(App::gh::Command);
use v5.10;
use App::gh::Utils;
use File::stat;
use File::Temp;
require App::gh::Git;

=head1 NAME

App::gh::Command::PullReq::Send - pull request of current branch.


=head1 USAGE

    $ gh pullreq send ([base branch]) ([owner]/[repo])

Base branch: the branch you fork from.

Owner/Repo:  the repository you fork from.


    $ gh pullreq send

    $ gh pullreq send master c9s/App-gh

=head1 API

API Spec is from L<>

    pull[base] - A String of the branch or commit SHA that you want your
        changes to be pulled to.

    pull[head] - A String of the branch or commit SHA of your changes.
        Typically this will be a branch. If the branch is in a fork of the original
        repository, specify the username first: "my-user:some-branch".

    pull[title] - The String title of the Pull Request (and the related Issue).

    pull[body] - The String body of the Pull Request.


sub parse_uri {
    my ($uri) = @_;
    if ( $uri =~ m{(git|https?)://*?)/(.*?).git} ) {
        return ($2,$3,$1);
    } elsif ( $uri =~ m{git\*?)/(.*?).git} ) {
        return ($1,$2,'git');
    return undef;

sub get_remote {
    my $self = shift;
    my $config = App::gh->config->current();
    my %remotes = %{ $config->{remote} };
    # try to get origin remote
    return $remotes{origin} || (values( %remotes ))[0];

sub run {
    my $self = shift;

    unless ( $ENV{EDITOR} ) {
        say "\$EDITOR is not set. please set the EDITOR environment variable for editing.";
        say "\nUnix-like system users: \n";
        say "\tNano text editor, a simple text editor";
        say "\t\t export EDITOR=nano";
        say "\tVIM users please run:";
        say "\t\t export EDITOR=vim";
        say "\tEmacs users please run:";
        say "\t\t export EDITOR=emacs";

        say "\nWindows users please run:\n";
        say "\t\t set EDITOR=notepad.txt";
        say "";

    my $remote_branch = shift ||'master';
    my $base          = shift;
    my ($user,$repo,$uri_type);
    if( $base ) {
        ($user,$repo) = split m{[/:]},$base;

    } else {
        my $remote = $self->get_remote();
        die "Remote not found\n." unless $remote;
        ($user, $repo, $uri_type ) = parse_uri( $remote->{url} );

    my $gh_id = App::gh->config->github_id;
    my $gh_token = App::gh->config->github_token;
    unless( $gh_id && $gh_token ) {
        die "Github authtoken not found. Can not send pull request.\n";

    my $local_repo = App::gh->git;
    open my $fh, '<', $local_repo->wc_path()."/.git/HEAD";
    my $ref = <$fh>;
    close $fh;
    chomp( $ref );

    my ($branch) = ( $ref =~ m{ref:\s\S+?/\S+?/(\S+)} );

    my $f = File::Temp->new(SUFFIX => ".md");
    my $t = stat($f->filename)->mtime;

    open $fh , ">" , $f->filename;
    print $fh "Title\n";
    print $fh "Body (markdown format)\n";
    close $fh;

    # launch editor
    system $ENV{EDITOR}, $f->filename;

    if ($t == stat($f->filename)->mtime) {
        info "No changes. Pull request was not sent.";

    open $fh, '<', $f->filename;
    my $content = do { local $/; <$fh> };
    close $fh;
    my ($title, $body) = split("\n", $content, 2);
    chomp( $title );
    chomp( $body );

    if (length($title) == 0 || length($body) == 0) {
        info "Message should two lines at least.";

    info "Sending pull request for $branch...";
    # XXX: make arguments into hash format
    my $data = App::gh->api->pullreq_send($user, $repo, $branch, $remote_branch, $title, $body);

    info "Sent: " . $data->{pull}->{html_url};