#!/bin/bash

set -e
set -u

export APPSH_HOME=$(cd $(dirname "$0")/.. && pwd)

. $APPSH_HOME/lib/common
# HEADER END

# TODO: Add a 'get' command that returns a single value
# If -r (required) given, exit with 0 if found, 1 otherwise.
#
# TODO: Add -s (shell) output:
#
#     $ app-conf get -s maven.artifact_id
#     MAVEN_ARTIFACT_ID=..
#
# Can be used like this:
#
#     set -- `app-conf get -s maven.artifact_id maven.group_id`

format_conf() {
  local IFS==
  while read key value
  do
    printf "%-20s %s" "$key" "$value"
    echo
  done
}

assert_valid_config_name() {
  local name=$1; shift
  local x="^$key_expr\\.$key_expr$"
  if [[ ! $name =~ $x ]]
  then
    fatal "Invalid name: $name"
  fi
}

conf_set() {
  local file=$1; shift
  local name=$1; shift
  local value=$1; shift

  assert_valid_config_name "$name"

  local d=`dirname "$file"`
  if [ ! -d "$d" ]
  then
    fatal "Not a directory: $d"
  fi

  if [ -r "$file" ]
  then
    sed "/^$name[ ]*=.*/d" "$file" > "$file.tmp"
  fi

  echo "$name=$value" >> "$file.tmp"
  mv "$file.tmp" "$file"
}

conf_delete() {
  local file=$1; shift
  local name=$1; shift

  assert_valid_config_name "$name"

  sed "/^$name[ ]*=.*/d" $file > $file.tmp
  mv $file.tmp $file
}

conf_import() {
  local dst=$1; shift
  local src=$1; shift

  echo "Importing config from $src"
  app-cat-conf -f "$dst" -f "$src" > "$dst.tmp"
  mv "$dst.tmp" "$dst"
}

usage_text() {
  echo "usage: $usage_app conf [-l location] <command>"
  echo ""
  echo "Available commands:"
  echo "  get [name]         - returns a single value"
  echo "  list               - list all config values"
  echo "  set [name] [value] - set a config parameter"
  echo "  delete [name]      - deletes a config parameter"
  echo "  import [file]      - import a file"
  echo ""
  echo "list is the default command."
  echo ""
  echo "Location is one of:"
  echo "  a or app, selects .app/config"
  echo "  u or user, selects ~/.appconfig"
  echo "  s or system, selects \$APPSH_HOME/lib/default-config"
  echo ""
  echo "Location is ignored for import."
  exit 1
}

_get_config_file_app config_a

location=app
while getopts "l:" opt
do
  case $opt in
    l)
      location="$OPTARG"
      shift 2;
      ;;
    *)
      break
      ;;
  esac
done

file=$location
location_to_file file

if [ $# -gt 0 ]
then
  command=$1
  shift
else
  command=list
fi

case "$command" in
  get)
    if [ $# != 1 ]
    then
      usage
    fi

    app-cat-conf -l "$location" -k "$1" | cut -f 2- -d =
    ;;
  list)
    if [ $# -gt 0 ]
    then
      usage "Extra arguments."
    fi

    app-cat-conf -l "$location" | format_conf
    ;;
  set)
    while getopts "f:" opt
    do
      case $opt in
        f)
          file="$OPTARG"
          shift 2;
          ;;
        *)
          usage "Unknown argument: $OPTARG"
          ;;
      esac
    done

    if [ $# -ne 2 ]
    then
      usage "Expected exactly two arguments."
    fi

    conf_set "$file" "$1" "$2"
    ;;
  delete)
    if [ $# -ne 1 ]
    then
      usage "Missing [name] argument."
    fi

    conf_delete "$file" "$1"
    ;;
  import)
    if [ $# -ne 1 ]
    then
      usage "Missing [file] argument."
      exit 1
    fi

    assert_is_app -C

    conf_import "$config_a" "$1"
    ;;
  *)
    if [ -z "$command" ]
    then
      usage
    else
      usage "Unknown command: $command"
    fi
    exit 1
    ;;
esac