#!/bin/bash

# Copyright (C) 2019 IoT.bzh
# Authors:
#    Stephane Desneux <stephane.desneux@iot.bzh>
#    Ronan Le Martret <ronan.lemartret@iot.bzh>
# Released under the Apache 2.0 license

set -e

# project vars
VERSION="1.0.0"
SCRIPTS_DIR=/libexec/pr-tools/customize
DETECTION_OUTPUT_DIR=/etc/platform-info
ALLSTEPS="core devices"

# script vars
SCRIPTNAME=$(basename $BASH_SOURCE)
DEBUG=false
SHOWVER=false
HELP=false

function info() { echo "$@" >&2; }
function error() { echo "ERROR: $@" >&2; }
function warning() { echo "WARNING: $@" >&2; }
function fatal() { echo "FATAL ERROR: $@" >&2; exit 2; }
function debug() { $DEBUG && echo "[$BASHPID] $@" >&2 || true; }

function usage() {
	cat <<EOF >&2
Usage: $SCRIPTNAME <option>

Options:
   -h|--help|--fullhelp: get help
   -V|--version: get version
   -d|--debug: enable debug
   -s|--step <name|dir>: set detection step by name or by directory (mandatory)
      If a name is given, a folder named $SCRIPTS_DIR/<name> is used for detection scripts.
      If a directory is given, it's used directly.
      Common names are: 'core','devices'
EOF
}

tmp=$(getopt -o h,V,d,s: --long help,version,debug,step: -n "$SCRIPTNAME" -- "$@") || {
	error "Invalid arguments."
	usage
	exit 1
}
eval set -- $tmp
while true; do
	case "$1" in
		-s|--step) STEP=$2; shift 2;;
		-d|--debug) DEBUG=true; shift;;
		-V|--version) SHOWVER=true; shift;;
		-h|--help) HELP=true; shift;; 
		--) shift; break;;
		*) fatal "Internal error";;
	esac
done


function run_script() {
	local sc=$1; shift
	info "Running: $sc $@"
	bash $sc "$@"|| { error "script $sc FAILED with $?"; return 1; }

	# check if script is only for firstboot based on its name
	# if so, remove it to prevent further executions
	local n=$(basename $sc)
	if [[ "$n" =~ ^[0-9]+(FB|firstboot)_ ]]; then
		info "Removing script $sc (firstboot only)"
		rm $sc
	fi
	return 0
}

# --------------------------------------------------------------

$SHOWVER && { echo $VERSION; exit 0; }
$HELP && { usage; exit 1; }

[[ -n "$STEP" && -d "$SCRIPTS_DIR/$STEP" ]] && STEP="$SCRIPTS_DIR/$STEP" 
[[ ! -d "$STEP" ]] && { error "Invalid step directory or name '$STEP'"; usage; exit 1; }

debug "Resolved scripts folder: STEP=$STEP"

for x in $ALLSTEPS; do
	infos=$DETECTION_OUTPUT_DIR/$x
	[[ ! -f $infos ]] && continue;
	debug "Sourcing $infos"
	. $infos || { error "Unable to source $infos"; exit 2; }
done

# always include 'common' dir
LISTDIR="${SCRIPTS_DIR}/common"

# environment must contain the following variables: CPU_ARCH, SOC_VENDOR, BOARD_MODEL
CATEGORIES="\
   CPU_ARCH \
   SOC_VENDOR \
   BOARD_MODEL \
"
for key in $CATEGORIES; do
	hwkey="HW_$key"

	[[ -z "${!hwkey}" ]] && { error "$hwkey is not set - please check files in $CONFIGDIR"; exit 1; }

	# map key to folder name
	case $hwkey in
		CPU_ARCH)		dirname=arch;;
		SOC_VENDOR)		dirname=vendor;;
		BOARD_MODEL)	dirname=board;;
		*)				dirname=${key,,} # key in lowercase
	esac

	LISTDIR="${LISTDIR} ${SCRIPTS_DIR}/$dirname/${!hwkey}"
done

# then iterate on each found dir and run scripts inside
debug "LISTDIR: $LISTDIR"
for dir in $LISTDIR; do
	if [[ -d $dir ]]; then
		for sc in $(ls $dir);do
			run_script $dir/$sc
		done
	fi
done
