#!/bin/bash
### gitmanage - Git server management client ###
### Download: wget http://<git-server>/gitmanage && chmod +x gitmanage ###

GITMANAGE_URL="${GITMANAGE_URL:-}"
GITMANAGE_TOKEN="${GITMANAGE_TOKEN:-}"
_CFG="${GITMANAGE_CONFIG:-$HOME/.gitmanage}"

if [ -f "$_CFG" ]; then
  while IFS='=' read -r key val; do
    key="${key%%[[:space:]]*}"; val="${val#"${val%%[! ]*}"}"
    [[ "$key" =~ ^# ]] && continue
    case "$key" in
      url)   [ -z "$GITMANAGE_URL" ]   && GITMANAGE_URL="$val" ;;
      token) [ -z "$GITMANAGE_TOKEN" ] && GITMANAGE_TOKEN="$val" ;;
    esac
  done < "$_CFG"
fi

usage() {
  cat <<EOF
Usage: gitmanage [--server <url>] [--token <token>] <command>

Commands:
  repo list
  repo create <name>
  repo delete <name>
  user list
  user add <username> <password>
  user passwd <username> <newpassword>
  user delete <username>

Config file (~/.gitmanage):
  url=http://<git-server>/gitmanage.php
  token=<shared-secret>

Environment variables: GITMANAGE_URL, GITMANAGE_TOKEN
EOF
  exit 1
}

while [[ "$1" == --* ]]; do
  case "$1" in
    --server) GITMANAGE_URL="$2";   shift 2 ;;
    --token)  GITMANAGE_TOKEN="$2"; shift 2 ;;
    --config) _CFG="$2";            shift 2 ;;
    --help)   usage ;;
    *) echo "Unknown option: $1" >&2; usage ;;
  esac
done

if [ -z "$GITMANAGE_URL" ]; then
  echo "Error: server URL not set. Use --server, GITMANAGE_URL, or ~/.gitmanage" >&2
  exit 1
fi

_post() {
  local action="$1"; shift
  local args=(-sf --data-urlencode "action=$action")
  while [ $# -gt 0 ]; do args+=(--data-urlencode "$1"); shift; done
  [ -n "$GITMANAGE_TOKEN" ] && args+=(--data-urlencode "token=$GITMANAGE_TOKEN")
  curl "${args[@]}" "$GITMANAGE_URL"
}

# Extract a single string field from a JSON response
_json_field() {
  # Usage: _json_field <json> <fieldname>
  echo "$1" | grep -oE "\"$2\":\"[^\"]*\"" | head -1 | cut -d'"' -f4
}

# Extract a JSON array of strings into newline-separated output
_json_array() {
  # Usage: _json_array <json> <fieldname>
  echo "$1" | grep -oE "\"$2\":\[[^]]*\]" | grep -oE '"[^"]*"' | grep -v "\"$2\"" | tr -d '"'
}

_check() {
  local result="$1"
  if echo "$result" | grep -q '"status":"ok"'; then
    return 0
  else
    local msg; msg=$(_json_field "$result" message)
    echo "Error: ${msg:-unknown error}" >&2
    return 1
  fi
}

SUBCMD="$1"; shift 2>/dev/null || usage

case "$SUBCMD" in
  repo)
    case "$1" in
      list)
        result=$(_post repo_list)
        _check "$result" || exit 1
        items=$(_json_array "$result" repos)
        echo "${items:-(none)}" ;;
      create)
        [ -z "$2" ] && { echo "Usage: gitmanage repo create <name>" >&2; exit 1; }
        result=$(_post repo_create "name=$2")
        _check "$result" && echo "Created: $(_json_field "$result" repo)" ;;
      delete)
        [ -z "$2" ] && { echo "Usage: gitmanage repo delete <name>" >&2; exit 1; }
        result=$(_post repo_delete "name=$2")
        _check "$result" && echo "Deleted: $(_json_field "$result" deleted)" ;;
      *) usage ;;
    esac ;;
  user)
    case "$1" in
      list)
        result=$(_post user_list)
        _check "$result" || exit 1
        items=$(_json_array "$result" users)
        echo "${items:-(none)}" ;;
      add)
        [ -z "$2" ] || [ -z "$3" ] && { echo "Usage: gitmanage user add <username> <password>" >&2; exit 1; }
        result=$(_post user_add "username=$2" "password=$3")
        _check "$result" && echo "Added: $(_json_field "$result" user)" ;;
      passwd)
        [ -z "$2" ] || [ -z "$3" ] && { echo "Usage: gitmanage user passwd <username> <newpassword>" >&2; exit 1; }
        result=$(_post user_passwd "username=$2" "password=$3")
        _check "$result" && echo "Updated: $(_json_field "$result" user)" ;;
      delete)
        [ -z "$2" ] && { echo "Usage: gitmanage user delete <username>" >&2; exit 1; }
        result=$(_post user_delete "username=$2")
        _check "$result" && echo "Deleted: $(_json_field "$result" deleted)" ;;
      *) usage ;;
    esac ;;
  *) usage ;;
esac
