#!/usr/bin/env bash

command:pr-new() {
  require-auth
  get-args "?number:'none'"

  local owner="$(get-owner)"
  local repo="$(get-repo)"

  assert-inside-git-repo
  assert-repo-top-level
  assert-git-repo-is-clean

  get-default-remote-name
  get-branch-name
  get-parent-remote-name
  get-parent-owner-repo
  get-parent-base

  git fetch "$remote_name" "$branch_name" &> /dev/null ||
    abort "Can't fetch remote='$remote_name' branch='$branch_name' (did you push it?)"

  if [ "$(git rev-parse $branch_name)" != "$(git rev-parse $remote_name/$branch_name)" ]; then
    abort "Branch $branch_name is not in sync with branch $remote_name/$branch_name";
  fi

  git fetch "$parent_remote_name" "$parent_base" &> /dev/null ||
    abort "Can't fetch parent remote='$parent_remote_name' branch='$parent_base'"

  local diff="$(git diff $parent_remote_name/$parent_base..$branch_name)"
  if [ -z "$diff" ]; then
    abort "No changes between $parent_remote_name/$parent_base and $branch_name."
  fi

  local head="$owner:$branch_name"
  local base="$parent_base"
  local url="/repos/$parent_owner_repo/pulls"

  if [[ "$number" =~ ^[0-9]+$ ]]; then
    local prompt_msg="Attach PR $owner/$repo:$branch_name -> $parent_owner_repo:$parent_base to issue #$number? [yN]"
    local doit=$(prompt "$prompt_msg")
    if [[ "$doit" =~ ^[yY] ]]; then
      api-post "$url" "$(
        json-dump-object head "$head" base "$base" issue "$number"
      )"
      msg_ok="Attached PR to issue: $(JSON.get -s /html_url -)"
    else
      msg_ok=0
    fi
  else
    editor-title-body "
# New GitHub Pull Request
#
# Requesting that...
#   repo: $owner/$repo
#   branch: $branch_name
# ...be pulled into...
#   repo: $parent_owner_repo
#   branch: $parent_base
#
# Enter your pull request info at the top like this:
#
#   First line is the pull request subject
#
#   The pull request body comes here, after a blank line separating it from
#   the subject.
#
#   The body can be as many lines as needed, and is optional. Only the pull
#   request subject is required.
#
#------------------------------------------------------------------------------
$ git diff $parent_remote_name/$parent_base..$branch_name
$diff

#------------------------------------------------------------------------------
$ git log $parent_remote_name/$parent_base..$branch_name
$(git log $parent_remote_name/$parent_base..$branch_name)
"

    api-post "$url" "$(
        json-dump-object head "$head" base "$base" title "$title" body "$body"
    )"
    if OK; then
      msg_ok="New PR created: $(JSON.get -a /html_url -)"
    else
      msg_fail="New PR failed: $(JSON.get -a /errors/0/message -)"
    fi
  fi
}

command:pr-list() {
  get-args '?owner:get-owner/repo:get-repo'

  state=open
  "$do_all" && state=all

  title="Pull requests for '$owner/$repo' (state=$state):"

  report-list \
    "/repos/$owner/$repo/pulls?state=$state;sort=updated;per_page=PER_PAGE" \
    'number state title user/login created_at updated_at head/label base/label'
}

format-entry:pr-list() {
  if "$raw_output"; then
    echo "$2"
  else
    printf "#%-3d %-8s %s\n     @%-12s Created: %s  Updated: %s\n     %s\n" \
      "$2" "($3)" "$4" "$5" "${6/T*/}" "${7/T*/}" "$8 → $9"
  fi
}

command:pr-diff() {
  get-args '?owner:get-owner/repo:get-repo' number
  api-get "/repos/$owner/$repo/pulls/$number"
}

ok:pr-diff() {
  head_url="$(JSON.get -s /head/repo/ssh_url -)"
  head_sha="$(JSON.get -s /head/sha -)"
  head_ref="$(JSON.get -s /head/ref -)"
  git fetch "$head_url" "$head_ref" &> /dev/null

  base_url="$(JSON.get -s /base/repo/ssh_url -)"
  base_sha="$(JSON.get -s /base/sha -)"
  base_ref="$(JSON.get -s /base/ref -)"
  git fetch "$base_url" "$base_ref" &> /dev/null

  git diff "$base_sha" "$head_sha"
}

command:pr-fetch() {
  get-args '?owner:get-owner/repo:get-repo' number
  assert-inside-git-repo
  if [ -n "$(git branch | grep -E "^PR/$number$")" ]; then
    echo "Branch PR/$number already exists"
  else
    git fetch -f "git@github.com:$owner/$repo" "refs/pull/$number/head:PR/$number" ||
        error "can't fetch PR $number"
  fi
  msg_ok=0
}

command:pr-merge() {
  get-args '?owner:get-owner/repo:get-repo' number '?message'
  # TODO Support merge message
  local json='{}'
  api-put "/repos/$owner/$repo/pulls/$number/merge" "$json"
}

command:pr-queue() {
  get-args '?user:get-user'
  local option1= option2=
  [ -n "$count_option" ] && option1=" --count=$count_option"
  $do_all && option2=" --all"

  for repo in `git hub repos $user -r$option1`; do
    local pulls="`git hub pr-list $repo$option2`"
    if [[ ! "$pulls" =~ --None-- ]]; then
      echo
      echo "$pulls"
    fi
  done
  set +x

  msg_ok=0
}

# vim: set ft=sh lisp:
