# This is a set of functions to check the LOCAL_* variables defined by user;
# They are intended to return correct response in case of incorrect user input.

# ***********************************************
# Functions of verification of abstract arguments

# $(call assert,condition,message)
define assert
  $(if $1,,$(error $(LOCAL_NAME): Assertion failed: $2))
endef

# $(call assert-file-exists,wildcard-pattern)
# Assert is disabled: $(call assert,$(wildcard $1),$(if $2,$2:The file "$1" does not exists,The file "$1:$($1)" does not exists))
define assert-file-exists
endef

# $(call assert-file-var-exists,filename(variable))
# Assert is disabled: $(call assert,$(wildcard $($1)),The file "$1:$($1)" does not exists)
define assert-file-var-exists
endef

# $(call assert-path-exists,path,var-name(optional))
# Assert is disabled: $(call assert,$(wildcard $1),$(if $2,$2:The path "$1" does not exists,The path "$1:$($1)" does not exists))
define assert-path-exists
endef

# $(call assert-path-var-exists,path(variable))
# Assert is disabled: $(call assert,$(wildcard $($1)),The path "$1:$($1)" does not exists)
define assert-path-var-exists
endef

# $(call assert-not-null,make-variable)
define  assert-not-null
  $(call assert,$($1),The variable "$1" is null)
endef

# $(call assert-list-not-null,make-list-variables)
define assert-list-not-null
  $(foreach i,$(1),
    $(call assert-not-null,$(i)))
endef

# $(call show-list-not-null,make-list-variables)
define show-list-not-null
  $(foreach i,$(1),
    $(if $($i),,
      $(shell echo $i has no value > /dev/stderr)))
endef

# $(call find-program,wildcard-pattern)
define find-program
  $(wildcard \
  $(addsuffix /$1, \
  $(sort \
  $(subst :, , \
  $(subst ::,:.:, \
  $(patsubst :%,.:%, \
  $(patsubst %:,%:.,$(PATH))))))))
endef

define assert-find-program
  $(call assert,$(strip $(call find-program,$(1))),The $(1) was not found in the path!)
endef

# $(call assert-find-file-inside-the-path,filename,path,var-name(optional))
# Assert is disabled: $(call assert-path-exists,$2,$3)
# Assert is disabled: $(call assert,$(shell find -L $(2) -type f -name $(1)), The $(1) was not found in the $(if $3,$3:,)$(2)!)
define assert-find-file-inside-the-path
endef

# $(call assert-variable-in-list,var-name,list)
define assert-variable-in-list
  $(call assert,$(filter $($(1)),$(2)),The variable $1 must be in [$(2)] but it is "$($1)")
endef

# $(call eq,var1,var2)
eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))

# ($call range,val,low,high)
range = $(shell if [ $(1) -ge $(2) -a $(1) -le $(3) ] ; then echo pass ; else echo miss ; fi)

define assert-variable-in-range
  $(call assert,$(call eq,$(call range,$($1),$(2),$(3)),pass),$1=$($1) is out of range [$(2) $(3)])
endef

# *******************************************************
# Functions of verification of project specific arguments

_local_chips := \
  msm8x26 \
  msm8916 \
  msm8929 \
  msm8936 \
  msm8952 \
  msm8953 \
  msm8956 \
  msm8974 \
  msm8992 \
  msm8994 \
  msm8996 \
  msm8998 \
  sdm439 \
  sdm450 \
  sdm660 \
  sdm670 \
  sdm845 \
  sm6150 \
  sm7150 \
  sm7225 \
  sm7250 \
  sm8150 \
  sm8250 \
  exynos3250 \
  exynos3475 \
  exynos5420 \
  exynos5422 \
  exynos5430 \
  exynos5433 \
  exynos7420 \
  exynos7570 \
  exynos7580 \
  exynos7870 \
  exynos7880 \
  exynos7885 \
  exynos8890 \
  exynos8895 \
  exynos9110 \
  exynos9810 \
  exynos9820 \
  mt6765 \
  mt6768

define check-local-chip
  $(call assert-variable-in-list,LOCAL_CHIP,$(_local_chips))
endef

define check-local-build-tool
  $(call assert-variable-in-list,LOCAL_BUILD_TOOL,arm llvm)
endef

define check-local-platform
  $(call assert-variable-in-list,LOCAL_PLATFORM,blowfish tbase qsee host)
endef

define check-local-link-gp-tee
  $(call assert-variable-in-list,LOCAL_LINK_GP_TEE,y n)
endef

define check-local-qsee-unprotected-mem
  $(call assert-variable-in-list,LOCAL_QSEE_UNPROTECTED_MEM,y n)
endef

define check-local-sign-type
  $(call assert-variable-in-list,LOCAL_SIGN_TYPE,remotely local)
endef

define check-local-qsee-proc
  $(call assert-variable-in-list,LOCAL_QSEE_PROC,scorpion A53_64)
endef

define check-local-api-level
  $(call assert-variable-in-range,LOCAL_API_LEVEL,1,12)
endef

define check-local-fips-crypto
  $(call assert-variable-in-list,LOCAL_FIPS_CRYPTO,y n)
endef

define check-local-disable-fatal-linker-warning
  $(call assert-variable-in-list,LOCAL_DISABLE_FATAL_LINKER_WARNINGS,true false)
endef

define check-local-sdk-path
  $(call assert-path-var-exists,LOCAL_SDK_PATH)
endef

define check-local-ndk-path
  $(call assert-path-var-exists,LOCAL_NDK_PATH)
endef

define check-local-keyfile
  $(call assert-file-var-exists,LOCAL_KEYFILE)
endef

define check-local-name
  $(call assert-not-null,LOCAL_NAME)
endef

define check-local-uuid
  $(call assert-not-null,LOCAL_UUID)
endef

# define check-local-target-name
#   $(call assert-variable-in-list,LOCAL_TARGET_NAME,exynos8890 driver-exynos8890 arm_blowfish msm8996)
# endef

# define check-local-group-id
#   $(call assert-variable-in-list,LOCAL_GROUP_ID,dev_ta dev_drv)
# endef


# *******************************************************
# debug functions

define dbg-check-by-var-name
  $(if $(call eq,$(V),1), \
    $(info checking rules of $(strip $(1)) = $($(strip $(1)))) \
  )
endef

define dbg-show-all-locals
  $(foreach _var,$(filter LOCAL_%,$(.VARIABLES)), \
  $(info $(_var) = $($(_var))))
endef

define dbg-show-all-targets
  $(foreach _var,$(filter TARGET_%,$(.VARIABLES)), \
  $(info $(_var) = $($(_var))))
endef

define dbg-show-all-configs
  $(foreach _var,$(filter CONFIG_%,$(.VARIABLES)), \
  $(info $(_var) = $($(_var))))
endef


# *******************************************************
# Automatic functions

# $(call und-to-dash,text)
_underline := _
_dash := -
define und-to-dash
  $(subst $(_underline),$(_dash),$(1))
endef

# $(call lowcase,uppercased-text)
define lowcase
  $(shell echo $1 | tr 'A-Z' 'a-z')
endef

# $(call var-name-trans,uppercased-underlined-text)
define var-name-trans
  $(call und-to-dash,$(call lowcase,$(1)))
endef

# $(call var-to-func,var-name)
define var-to-func
  check-$(strip $(call var-name-trans,$(1)))
endef

# if checker is not exists do nothing
# $(call call-func-by-var-optional,var-name)
define call-func-by-var-optional
  $(call dbg-check-by-var-name, $1) \
  $(eval _v := $(call var-to-func,$(strip $(1)))) \
  $(call $(_v))
endef

# $(call check-common-rule-list,list)
define check-common-rule-list
  $(foreach _var,$(1),$(call call-func-by-var-optional,$(_var)))
endef


# *******************************************************
# Platform's functions of conditions

define check-tbase-llvm
  $(if $(call eq,$(LOCAL_BUILD_TOOL),llvm), \
    $(call assert-not-null,LOCAL_CROSS_GCC_PATH_LGCC) \
    $(call assert-not-null,LOCAL_CROSS_GCC_PATH) \
    $(call assert-path-var-exists,LOCAL_CROSS_GCC_PATH_LGCC) \
    $(call assert-path-var-exists,LOCAL_CROSS_GCC_PATH))
endef

define check-qsee-llvm
  $(if $(call eq,$(LOCAL_BUILD_TOOL),llvm), \
    $(call assert-not-null,LOCAL_LLVM_ROOT) \
    $(call assert-not-null,LOCAL_LLVM_VERSION) \
    $(call assert-path-exists,/$(LOCAL_LLVM_ROOT)/$(LOCAL_LLVM_VERSION),LOCAL_LLVM_ROOT/LOCAL_LLVM_VERSION))
endef

define check-qsee-aarch64-root
  $(if $(call eq,$(LOCAL_BUILD_TOOL),llvm), \
    $(if $(call eq,$(LOCAL_QSEE_PROC),A53_64), \
      $(call assert-not-null,LOCAL_AARCH64_ROOT) \
      $(call assert-path-exists,/$(LOCAL_AARCH64_ROOT),LOCAL_AARCH64_ROOT)))
endef

define check-qsee-arm7-root
  $(if $(call eq,$(LOCAL_BUILD_TOOL),llvm), \
    $(if $(call eq,$(LOCAL_QSEE_PROC),scorpion), \
      $(call assert-not-null,LOCAL_ARM7_ROOT) \
      $(call assert-path-exists,/$(LOCAL_ARM7_ROOT),LOCAL_ARM7_ROOT)))
endef

define check-tbase-qsee-armcc
  $(if $(call eq,$(LOCAL_BUILD_TOOL),arm), \
    $(call assert-not-null,LOCAL_ARMCC_LICENSE) \
    $(call assert-path-var-exists,LOCAL_ARMCC_PATH))
endef

define check-fips-imprint-tool
  $(if $(call eq,$(LOCAL_FIPS_CRYPTO),y), \
    $(call assert-not-null,LOCAL_IMPRINT_TOOL) \
    $(call assert-path-var-exists,LOCAL_IMPRINT_TOOL))
endef

# *******************************************************
# Platform functions

# $(call dbg-show-all-locals)
# $(call dbg-show-all-configs)
# $(call dbg-show-all-targets)

define skip-line
  $(if $(call eq,$(V),1), \
    $(info ) \
  )
endef

define qsee-build-rules
  $(call skip-line) \
  $(call assert-file-exists,$(LOCAL_SDK_PATH)/trustzone_images/build/ms/target.*) \
  $(call assert-path-exists,$(LOCAL_SDK_PATH)/trustzone_images/build/ms) \
  $(call check-tbase-qsee-armcc) \
  $(call check-qsee-llvm) \
  $(call check-local-qsee-proc) \
  $(call check-fips-imprint-tool) \
  $(call check-qsee-arm7-root) \
  $(call check-qsee-aarch64-root) \
  $(call check-common-rule-list, \
    LOCAL_NAME \
    LOCAL_CHIP \
    LOCAL_SDK_PATH \
    LOCAL_LINK_GP_TEE \
    LOCAL_TARGET_NAME \
    LOCAL_GROUP_ID \
    LOCAL_OUT \
    LOCAL_BUILD_TOOL \
    LOCAL_IMPRINT_TOOL \
    LOCAL_FIPS_CRYPTO \
    LOCAL_QSEE_UNPROTECTED_MEM \
    LOCAL_QSEE_ACCEPT_BUFFER_SIZE \
    LOCAL_QSEE_BRANCH)
endef

define tbase-build-rules
  $(call skip-line) \
  $(call assert-find-file-inside-the-path,TlApi.lib,$(LOCAL_SDK_PATH),LOCAL_SDK_PATH) \
  $(call check-tbase-qsee-armcc) \
  $(call check-tbase-llvm) \
  $(call check-local-api-level) \
  $(call check-fips-imprint-tool) \
  $(call check-common-rule-list, \
  LOCAL_NAME \
  LOCAL_SDK_PATH \
  LOCAL_BUILD_TOOL \
  LOCAL_CHIP \
  LOCAL_TARGET_NAME \
  LOCAL_LINK_GP_TEE \
  LOCAL_OUT \
  LOCAL_FIPS_CRYPTO)
endef

define blowfish-build-rules
  $(call skip-line) \
  $(call assert-find-file-inside-the-path,libtzsl.so,$(LOCAL_SDK_PATH)/../../platforms) \
  $(call check-common-rule-list, \
  LOCAL_NAME \
  LOCAL_SDK_PATH \
  LOCAL_LINK_GP_TEE \
  LOCAL_TARGET_NAME \
  LOCAL_OUT)
endef

define host-build-rules
  $(call skip-line) \
  $(call assert-find-program,gcc) \
  $(call check-common-rule-list, \
  LOCAL_NAME \
  LOCAL_LINK_GP_TEE \
  LOCAL_LINK_EMULATOR_GP_CLIENT \
  LOCAL_GROUP_ID \
  LOCAL_FIPS_CRYPTO \
  LOCAL_OUT)
endef

define qsee-sign-rules
  $(call skip-line) \
  $(call assert-file-exists,$(LOCAL_SIGNCLIENT_JAR)) \
  $(call assert-file-exists,$(LOCAL_SDK_PATH)/trustzone_images/build/ms/target.*) \
  $(call check-common-rule-list, \
  LOCAL_NAME \
  LOCAL_CHIP \
  LOCAL_QSEE_PROC \
  LOCAL_UUID \
  LOCAL_OUT)
endef

define tbase-sign-rules
  $(call skip-line) \
  $(call assert-file-exists,$(LOCAL_SIGNCLIENT_JAR)) \
  $(call assert-find-file-inside-the-path,TlApi.lib,$(LOCAL_SDK_PATH)) \
  $(call check-local-api-level) \
  $(call check-common-rule-list, \
  LOCAL_NAME \
  LOCAL_UUID \
  LOCAL_DRIVER_ID \
  LOCAL_OUT)
endef

define blowfish-sign-rules
  $(call skip-line) \
  $(call assert-file-exists,$(LOCAL_SIGNCLIENT_JAR)) \
  $(call check-common-rule-list, \
  LOCAL_NAME \
  LOCAL_UUID \
  LOCAL_OUT)
endef

define host-sign-rules
  $(call skip-line) \
  $(call check-common-rule-list, \
  LOCAL_NAME \
  LOCAL_UUID \
  LOCAL_OUT)
endef
