#!/bin/sh

source /usr/bin/flexa-install
# gets the api-version
# 
# parameters:
#  $1: path to json-received from service portal
#
# returns:
#  1: old
#  2: new

api_version() {
  if [ ! -f $1 ]; then
    echo "0"
  else 
    if [[ $( grep "configUrl" $1) ]]; then
      echo "1"                                

    else   
      echo "0"
    fi
  fi

}


# checks if the directory and the config files 
# are in place
#
# parameters:
#  $1: service-json
#  $2: app-json
#
# returns:
#  1: 200 (-> ok)
#  2: 400 (-> not ok)

check_flexa_directories()
{
  if [ ! -f $1 ]; then
    echo 400
  fi
  if [ ! -f $2 ]; then
    echo 400
  fi

  echo 200
}

# gets the version of the installed application
# 
# parameters:
#  $1: service-json file

get_app_version() {
 
  version=$( jq -r '.version' $1 ) 
  echo ${version}
}

# sends post request
#
# parameters:
#   $1: parameters in json format
#   $2: output file
#   $3: url 
#
# returns:
#   responscode
# creates:
#   output file containing the response

post_request() {
  logger "sending request $1 to $3 ..."
  logger "$1"
  #logger " POST -H \"Content-Type: application/json\" -d $1 -s -o $2 -w \"%{http_code}\" $3"
  response=$( curl \
    -X POST \
    -H "Content-Type: application/json" \
    -d "$1" \
    --max-time 2 \
    -s \
    -o $2 \
    -w "%{http_code}" \
    $3 ) 
  #logger "sending request $1 to $3 ... Done: ${response}"
  echo ${response}
}


# sends post request based on the new API
# Note: new api contains the POST in the
#       Json's url filed
#
# parameters:
#   $1: parameters in json format
#   $2: output file
#   $3: url 
# returns:
#    responsecode
# creates:
#    output file containing the response    

post_request_new_api() {
  logger "sending request $1 to $3 ..."
  response=$( curl \
    -H "Content-Type: application/json" \
    -d $1 \
    --max-time 2 \
    -s \
    -o $2 \
    -w "%{http_code}" \
    -X $3 )
  logger "sending request $1 to $3 ... Done: ${response}"
  echo ${response}
}

# checks whether a command exixts or not
# Returns True or False
# parameters:
#   $1: name_of_the_program/command example <gedit> , <grep> etc

exists()
{
  command -v "$1" >/dev/null 2>&1
}


# Function for generating the data in json format to send to Flexa-registry.
# parameters:
#   $1: regId

generate_data(){                                                                                               
	VERSION=$(cat /barix/info/VERSION)
	DEVICE=$(cat /proc/sys/kernel/hostname)    
	# getting Hardware
	if exists qiba-spi-get-production-info.sh ; then                                                           
	HW=$(qiba-spi-get-production-info.sh -w)
cat <<EOF
{"regId":"$1", "DeviceInfo" :{ "Firmware version": "$VERSION" , "Device": "$DEVICE" , "HW":${HW} }
}                                                                                                              
EOF
# In case accessing the device hardware is ot possible                                                    
else 
cat <<EOF
{"regId":"$1", "DeviceInfo" :{ "Firmware version": "$VERSION" , "Device": "$DEVICE" } 
}             
EOF
fi
}

# requests information from registry and stores 
# received config
#
# parameters:
#   $1: storage path for registry-config file
#   $2: regId
#   $3: registry-url

request_registry_info() {
  DATA_JSON=$(generate_data $2)
  logger "flexa-config-lib: Contacting Registry for service URL"
  for i in 1 2 3 4 5 6 7 8 9 10; do 
    #registry_response=$( post_request '{"regId":'"'$2'"'}' $1 $3 )
    registry_response=$( post_request "${DATA_JSON}" $1 $3 ) 
    echo "${registry_response}"
    if [ "${registry_response}" = "200" ]; then
      local extension="/GetURL"	
      service_url="$( jq -r '.url' $1 )${extension}"
      logger "flexa-config-lib: Contacting flexa-registry... Done!"
      uci set flexa_agent.service.service_url="${service_url}"
      uci commit
      break    
    else
      logger "flexa-config-lib: Contacting flexa-registry failed! Attempt: $i / 3"
    fi
  done
}

# downloads the new application package, if 
# necessary
#
# parameters:
#  $1: new_version
#  $2: package-url
#  $3: target-path to store the package
# Edit : to deal with spaces in package url ${package_url// /%20}

get_package() {
  #echo "get package!"
  logger $1 $2 $3
  old_version=$( uci get flexa_agent.service.package_version )
  #echo "version comparison: ${old_version} $1"
  if [ ${old_version} != "$1" ]; then
    
    logger "downloading new package from $2 ..."

    if curl --max-time 20 "${2// /%20}" -o $3; then 
      logger "downloading new package from $2 ... Done!"
      uci set flexa_agent.service.package_version="$1"
      uci commit
       
      echo 200
    else
      logger "downloading application package from ${package_url} TO $3 ... failed!"
      echo 400
    fi
  else
    echo 201
  fi 
}


# gets the application configuration from the
# service portal 
#
# parameters
#  $1: storage path for config file 
#  $2: regId
#  $3: config-url

get_config() {
  logger "Contacting flexa-service for configuration..."
  
  for i in 1 2 3; do

    config_response=$( post_request '{"regId":"'$2'"}' $1 $3 )
    echo ${config_response}
    if [ "${config_response}" = "200" ]; then
      app_param_to_uci $1
      update_rate_to_uci $1
      logger "Contacting flexa-service for configuration... Done!"
      break
    else
      logger "Contacting flexa-service for configuration... Failed! Attempts $i / 3"
    fi
  done
}


# requests information from service and stores 
# received config, checks if there is a new 
# package and requests config
#
# parameters:
#   $1: storage path for registry-config file
#   $2: regId
#   $3: service-url

 request_service_info() {
  logger "Contacting flexa-service..."
  
  for i in 1 2 3; do
 
    service_response=$( post_request '{"regId":"'$2'"}' $1 $3 )
    #echo -e  "\n\n Requesting service info"
    echo ${service_response}
    

    if [ "${service_response}" = "200" ]; then
      length=$(jq 'length' $1 )
      #echo "length "$length
      if [ ${length} -ge 5 ]; then
        api_version="new"
        #uci set flexa_agent.service.api_version='new'
        #echo "NEW API ENCOUNTERED"
        package_url=$( jq -r '.packageUrl' $1 | awk '{ print $0 }' ) 
        setStatusUrl=$( jq -r '.setStatusUrl' $1 | awk '{ print $2 }' )
        methodsetStatusUrl=$( jq -r '.setStatusUrl' $1 | awk '{ print $1 }' )
        status_url=${setStatusUrl}
        uci set flexa_agent.service.status_url="${status_url}"
        getConfigUrl=$( jq -r '.getConfigUrl' $1 | awk '{ print $2 }' )
        methodgetConfigUrl=$( jq -r '.getConfigUrl' $1 | awk '{ print $1 }' )
        #echo "bla: ${getConfigUrl}"
        config_url=${getConfigUrl}
        new_version=$(cat $1 | jq -r '.version')
      else
        #echo -e "\n\n\nold_api"
        api_version="old"
        package_url=$( cat $1 | jq -r '.packageUrl' ) 
        config_url=$( cat $1 | jq -r '.configUrl' ) 
        new_version=$(cat $1 | jq -r '.version')
        #echo -e "url : ${url} \nconfig url ${config_url}"
      fi	
      #echo "getting here"
      logger "Contacting service... Done!"
      uci set flexa_agent.service.config_url="${config_url}"
      uci set flexa_agent.service.package_url="${package_url}"
      uci set flexa_agent.service.api_version="${api_version}"	
      	
      # why is it commented?
      #uci set flexa_agent.service.new_version="${new_version}"
      uci commit
      #echo " Parameters successfully saved"
    
    else
      logger "Contacting service... Failed! Attempt $i / 3"
      echo -e "\n\nCouldn't get service info"
    fi
    break
  done
}


# checks the config state via flexa-api
#
# parameters:
#   $1: storage path for status file
#   $2: regId
#   $3: status-url

request_status_info() {
  logger "Contacting flexa-service to check config state..."
  echo "Contacting flexa-service to check config state..."

  #echo "Contacting flexa-service to check config state..."
  #echo "input: "$1 $2 $3
  for i in 1 2 3; do
    if [ $( uci get flexa_agent.service.api_version ) = "new" ]; then
      status_url=$( uci get flexa_agent.service.status_url ) 
       echo -e  "\n\n\n NEW API Status url : ${status_url}"
     else
       status_url=$3
       status_url=${status_url%/GetURL}/SetStatus	
    fi
    #echo -e  "\n\n\nStatus url : ${status_url}" 
    status_response=$( post_request '{"regId":'\"$2\"',"status":"Alive"}' $1 ${status_url} )
    echo "status response: "$status_response
    # tatus_response=$( post_request '{"regId":'"'$2'"',"status":"Alive"}' $1 ${status_url} )
     #curl -X POST -d '${params}' ${status_url}
    #echo "status response: "$status_response
    if [ "${status_response}"  = "200" ]; then
      #echo $3
      state=$( jq -r '.config' $1 )
      logger "Contacting flexa-service to check config state... Done!"
      echo ${status_response}
      break
    else
      echo ${status_response}
      #logger "Contacting flexa-service to check config state... Failed! Attempts $i / 3"
    fi
  done

}


# requests information from service and stores 
# received config, checks if there is a new 
# package and requests config. Uses the new api
#
# parameters:
#   $1: storage path for registry-config file
#   $2: regId
#   $3: service-url

contact_service() {
  logger "Contacting flexa-service..."
  
  for i in 1 2 3; do
    service_response=$( post_request_new_api '{"regId":"'$2'"}' $1 $3 )
    echo ${service_response}
    if [ "${registry_response}" = "200" ]; then
      package_url=$( jq -r '.packageUrl' $1 )	
      new_version=$( jq -r '.version' $1 )

      if [[ $( grep "configUrl" $1) ]]; then
        config_url=$( jq -r '.configUrl' $1 )                                        
    
      else   
        config_url=$( jq -r '.getConfigUrl' $1 ) 
      fi

      logger "Contacting service... Done!"
      uci set flexa_agent.service.config_url="${config_url}"
      uci set flexa_agent.service.package_url="${package_url}"
      #uci set flexa_agent.service.new_version="${new_version}"
      uci commit
      break
    else
      logger "Contacting service... Failed! Attempt $i / 3"
    fi
  done
}

# creates a cronjob for the flexa-agent based
# on received configration and removes old 
# cron jobs for the same application
#
# parameters:
#   $1: application name
#   $2: update rate in hours

submit_cronjob() {

  # remove cronjobs for application $1:
  crontab -l | grep -v $1 | crontab -
  #crontab -l | grep -v '/usr/bin/flexa-agent'  | crontab - 
  
  # cron job should be executed every $2 hours
  # get the current time (only minutes)
  MM=$( date "+%M" )
  echo "adding cronjob: "
  echo "${MM} */$2 * * * $1"
  echo " "
  # add job to crontab: 
  crontab -l | { cat; echo "${MM} */$2 * * * $1"; } | crontab -                                    
 
}


# converts json to uci-config
#
# parameters:
#  $1: json-file
#  $2: uci-module

json_to_uci() {


  n_keys=$( echo $1 | jq length )
  i="0"

  while [ $i -lt ${n_keys} ]; do
    key=$( echo $1 | jq keys[$i] | tr -d '"')
    value=$( echo $1 | jq .$key | tr -d '"')
    
    uci set "${2}.${key}"="${value}"
    
    i=$(( $i+1 ))
  done
  uci commit 

}


# passes the .AppParam part of the flexa-app config
# to json_to_uci
#
# parameters:
#  $1: json-file

app_param_to_uci() {

  input=$( jq .AppParam $1 )
  json_to_uci "${input}" "flexa_app.AppParam"

}


update_rate_to_uci() {

  update_rate=$( jq .UpdateRate $1 )
  submit_cronjob /usr/bin/flexa-agent 1
  uci set flexa_agent.service.update_rate="${update_rate}"
  uci commit 
}


# erases the flexa-app uci-config
# and resets the file
# 
# parameters:
#   $1: path to template
#   $2: path to flexa_app config

reset_flexa_app_config() {

  cp $1 $2  

}

reset_flexa_agent_config() {
  echo "resetting the flexa-agent's uci config"
  uci set flexa_agent.service.service_url="changeme"
  uci set flexa_agent.service.config_url="changeme"
  uci set flexa_agent.service.package_url="changeme"
  uci set flexa_agent.service.package_version="0"
  
  uci commit

}


              
                                                                     
          
                 
                 
           
                         
                                                
                

