#!/bin/bash
#########
#  ============LICENSE_START====================================================
#  org.onap.aaf
#  ===========================================================================
#  Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
#  ===========================================================================
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#  ============LICENSE_END====================================================
#


# Fill out "aaf.props" if not filled out already
if [ ! -e aaf.props ]; then
  > ./aaf.props
fi
 
. ./aaf.props

DOCKER=${DOCKER:=docker}
CADI_VERSION=${CADI_VERSION:=2.1.10-SNAPSHOT}

for V in VERSION DOCKER_REPOSITORY HOSTNAME CONTAINER_NS AAF_FQDN AAF_FQDN_IP DEPLOY_FQI APP_FQDN APP_FQI VOLUME DRIVER LATITUDE LONGITUDE; do
   if [ "$(grep $V ./aaf.props)" = "" ]; then
      unset DEF
      case $V in
	 DOCKER_REPOSITORY) 
	        PROMPT="Docker Repo"
	        DEF="nexus3.onap.org:10003"
	        ;;
	 HOSTNAME) 
	        PROMPT="HOSTNAME (blank for Default)"
	        DEF=""
	        ;;
         AAF_FQDN)   PROMPT="AAF's FQDN";;
         DEPLOY_FQI) PROMPT="Deployer's FQI";;
         AAF_FQDN_IP)
		# Need AAF_FQDN's IP, because not might not be available in mini-container
		PROMPT="AAF FQDN IP"
		LOOKUP=$(host "${AAF_FQDN}" | grep "has address")
		if [ -n "${LOOKUP}" ]; then
  		    DEF=$(echo ${LOOKUP} | tail -1 | cut -f 4 -d ' ')
                fi
                ;;
         APP_FQDN)   PROMPT="App's Root FQDN";;
         APP_FQI)    PROMPT="App's FQI"
		     if [[ "${APP_FQDN}" != *"."* ]]; then
	 	       DEF="${APP_FQDN}@${APP_FQDN}.onap.org"
                     fi
		     ;; 
         VOLUME)     PROMPT="APP's AAF Configuration Volume"
		     if [[ "${APP_FQDN}" != *"."* ]]; then
		       DEF="${APP_FQDN}_config"
		     fi
		 ;;
         DRIVER)     PROMPT=$V;DEF=local;;
         CONTAINER_NS)     
                     PROMPT=$V;DEF=onap;;
	 VERSION)    PROMPT="CADI Version";DEF=$CADI_VERSION;;
         LATITUDE|LONGITUDE) PROMPT="$V of Node";;
         *)          PROMPT=$V;;
      esac
      if [ "$DEF" = "" ]; then
           PROMPT="$PROMPT: "
      else 
           PROMPT="$PROMPT ($DEF): "
      fi
      read -p "$PROMPT" VAR 
      if [ "$VAR" = "" ]; then
         if [ "$DEF" = "" ]; then
            if [ "$V" != "HOSTNAME" ]; then
              echo "agent.sh needs each value queried.  Please start again."
              exit
            fi
         else
            VAR=$DEF
         fi
      fi
      echo "$V=$VAR" >> ./aaf.props
      declare "$V"="$VAR"
   fi
done
. ./aaf.props

# Make sure Container Volume exists
if [ "$($DOCKER volume ls | grep ${VOLUME})" = "" ]; then
  echo -n "Creating Volume: " 
  $DOCKER volume create -d ${DRIVER} ${VOLUME}
fi

if [ -n "$DOCKER_REPOSITORY" ]; then
  PREFIX="$DOCKER_REPOSITORY/"
else
  PREFIX=""
fi 

function run_it() {
  if [ -n "${DUSER}" ]; then
    USER_LINE="--user ${DUSER}"
  fi
  $DOCKER run  -it  --rm \
    ${USER_LINE} \
    -v "${VOLUME}:/opt/app/osaaf" \
    --add-host="$AAF_FQDN:$AAF_FQDN_IP" \
    --env AAF_FQDN=${AAF_FQDN} \
    --env DEPLOY_FQI=${DEPLOY_FQI} \
    --env DEPLOY_PASSWORD=${DEPLOY_PASSWORD} \
    --env APP_FQI=${APP_FQI} \
    --env APP_FQDN=${APP_FQDN} \
    --env LATITUDE=${LATITUDE} \
    --env LONGITUDE=${LONGITUDE} \
    --env aaf_locator_container_ns=${CONTAINER_NS} \
    --name aaf-agent-$USER \
    "$PREFIX"onap/aaf/aaf_agent:$VERSION \
    bash -c "bash /opt/app/aaf_config/bin/agent.sh $PARAMS"
}

function sso {
  if [ -n "$2" ]; then
    echo "$1=$2" >> ~/.aaf/sso.props
  fi
}

function reset_sso {
    mkdir -p ~/.aaf
    > ~/.aaf/sso.props
    sso aaf_locate_url "https://$AAF_FQDN:8095"
    sso cadi_latitude "$LATITUDE"
    sso cadi_longitude "$LONGITUDE"
    sso cadi_loglevel "DEBUG"
    TRUSTSTORE="$(ls truststore*.jks | tail -1)"
    if [ -z "$TRUSTSTORE" ]; then
      echo "Place a truststore*.jar which has YOUR CA in it here"
      exit
    fi
    sso cadi_truststore "${PWD}/${TRUSTSTORE}"
    sso cadi_truststore_password changeit
}

PARAMS=$@
case "$1" in 
  bash)
    PARAMS="&& cd /opt/app/osaaf/local && exec bash"
    run_it -it --rm  
    ;;
  taillog)
    run_it -it --rm 
    ;;
  aafcli) 
    shift
    reset_sso
    if [ -f aaf-auth-cmd-$VERSION*-full.jar ]; then
      java -Dcadi_prop_files="~\/.aaf\/sso.props" -jar aaf-auth-cmd-$VERSION*-full.jar $@
    else 
      echo "For local use, you need to have 'aaf-cadi-aaf-$VERSION*-full.jar' (or newer)"
    fi
    ;;
  local) 
    shift
    CMD="$1"
    if [ -z "$2" ]; then 
	CMD="$CMD $APP_FQI $APP_FQDN"
    else 
      if [ "-" = "$2" ]; then
         CMD="$CMD $APP_FQI"
      else
         CMD="$CMD $2"
      fi
      if [ "-" = "$3" ]; then
         CMD="$CMD $APP_FQDN"
      else
         CMD="$CMD $3"
      fi
    fi
    reset_sso
    sso aaf_id "$DEPLOY_FQI"
    sso aaf_password "$DEPLOY_PASSWORD"
    if [ -f aaf-auth-cmd-$VERSION*-full.jar ]; then
      mkdir -p $APP_FQDN
      java -Dcadi_prop_files="~\/.aaf\/sso.props" -cp aaf-auth-cmd-$VERSION*-full.jar org.onap.aaf.cadi.configure.Agent $CMD 
    else 
      echo "For local use, you need to have 'aaf-cadi-aaf-$VERSION*-full.jar' (or newer)"
    fi
    ;;
  *)
    run_it --rm 
    ;;
esac

