#!/usr/bin/env bash

set -e

command:issue-new() {
  require-auth
  get-args '?owner:get-user/repo:get-repo'

  local url="/repos/$owner/$repo/issues"

  editor-title-body "
# Creating a new issue for '$owner/$repo':
#
#   https://github.com/$owner/$repo/issues
#
# Enter your issue info at the top like this:
#
#   First line is the issue subject
#
#   The issue 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 issue
#   subject is required."

  api-post "$url" "$(
    json-dump-object title "$title" body "$body"
  )"

  if OK; then
    msg_ok="New issue created: '$(JSON.get -a /html_url -)'"
  else
    msg_fail="New issue failed: $(JSON.get -a /message -)"
  fi
}

command:issues() {
  get-args '?owner:get-user/repo:get-repo'

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

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

  report-list \
    "/repos/$owner/$repo/issues?state=$state;sort=updated;direction=desc;per_page=PER_PAGE" \
    'number updated_at state user/login title'
}

format-entry:issues() {
  if "$raw_output"; then
    echo "$2"
  else
    printf "#%-3d (%s) %-6s @%-16s %s\n" "$2" "${3/T*/}" "$4" "$5" "$6"
  fi
}

command:issue() {
  get-args '?owner:get-user/repo:get-repo' "number:'none'"
  if [[ ! "$number" =~ ^[0-9]+$ ]]; then
    command=issue-new
    command:issue-new
  else
    api-get "/repos/$owner/$repo/issues/$number"
  fi
}

ok:issue() {
  local label_title=Issue
  local label_body=Description
  fields=(
    title
    number
    html_url
    user__login
    state
    assignee__login
    milestone__title
    created_at body
    comments
  )
  local skip_field_comments=true
  if $pager_in_use; then
    echo -------------------------------------------------------------------------------
    write-issue
  elif interactive; then
    pager_in_use=true
    write-issue | $GIT_HUB_PAGER
  else
    write-issue
  fi
}

write-issue() {
  report-data

  local comments="$(JSON.get -n /comments -)"
  if [ "$comments" -gt 0 ]; then
    echo Comments:
    command=comments
    report-list \
      "/repos/$owner/$repo/issues/$number/comments?sort=updated;per_page=PER_PAGE" \
      'user/login updated_at body'
  fi
}

format-entry:comments() {
  printf "%d) %-14s (%s)\n" "$1" "$2" "${3/T*/}"
  local text
  normalize-multiline-text-output "$4" " "
  echo "$text"
  echo
  :
}

command:issue-close() {
  get-args '?owner:get-user/repo:get-repo' number
  api-patch "/repos/$owner/$repo/issues/$number" "$(
    json-dump-object state closed
  )"
}

command:issue-resolve() {
  get-args '?owner:get-user/repo:get-repo' number
  git hub comment $owner/$repo $number && git hub issue-close $owner/$repo $number
  msg_ok=0
}

command:issue-edit() {
  get-args '?owner:get-user/repo:get-repo' number
  api-get "/repos/$owner/$repo/issues/$number"

  old_title="$(JSON.get -s /title -)"
  old_state="$(JSON.get -s /state -)"
  old_assignee="$(JSON.get -a /assignee/login -)"
  old_milestone="$(JSON.get -a /milestone/number -)"

  local issue_report="$(git hub issue "$owner/$repo" "$number" | sed 's/^/# /')"

  editor-comment-state "
---
title: $old_title
state: $old_state
assignee: $old_assignee
milestone: $old_milestone
---
# You can edit the variables above, and even add a comment at the top.
#
# Valid values are:
#
#   title -- A string
#   state -- open | closed
#   assignee -- GitHub login of a user with push access
#   milestone -- The id # of the milestone
#
# ------------------------------------------------------------------------------
$issue_report"

  msg_ok=0

  if [ -z "$comment" ] &&
    [ "$title" == "$old_title" ] &&
    [ "$state" == "$old_state" ] &&
    [ "$assignee" == "$old_assignee" ] &&
    [ "$milestone" == "$old_milestone" ]
  then
    say "No changes made."
    return
  fi

  if [ -n "$comment" ]; then
    say "Comment added"
    api-post "/repos/$owner/$repo/issues/$number/comments" "$(
      json-dump-object body "$comment"
    )"
  fi

  if [ "$title" != "$old_title" ] ||
    [ "$state" != "$old_state" ] ||
    [ "$assignee" != "$old_assignee" ] ||
    [ "$milestone" != "$old_milestone" ]
  then
    [ -z "$title" ] && abort "title can't be empty"
    (
      [ -z "$state" ] && state=open
      [ -z "$assignee" ] && assignee=null
      [ -z "$milestone" ] && milestone=null

      api-patch "/repos/$owner/$repo/issues/$number" "$( \
        json-dump-object \
          title "$title" \
          state "$state" \
          assignee "$assignee" \
          milestone "$milestone" \
      )"
    ) || return 1

    if [[ "$title" != "$old_title" ]]; then
      say "Changed title to '$title'"
    fi
    if [[ "$state" != "$old_state" ]]; then
      say "Changed state to '$state'"
    fi
    if [[ "$assignee" != "$old_assignee" ]]; then
      say "Changed assignee to '$assignee'"
    fi
    if [[ "$milestone" != "$old_milestone" ]]; then
      say "Changed milestone to '$milestone'"
    fi
  fi
}

command:issue-update() {
  die "$command not yet implemented"
}

# vim: set lisp:
