import os
Import('env')

env = env.Clone()

target_name='wsm'

#------------------------------------------------------------------------------
# WSM SConscript functions
#------------------------------------------------------------------------------
def WSM_LOGD(str):
    print("[WSM_DBG] " + str)

# get SAFE env variable and print it
def local_get_env(env_variable):
    ret_env_variable = os.getenv(env_variable, 'environment variable not available')
    WSM_LOGD(env_variable + ' : ' + ret_env_variable)
    return ret_env_variable

CHIPSET = env['CHIPSET']
if CHIPSET == "waipio":
    CHIPSET = "sm8450"
WSM_LOGD("CHIPSET : "+CHIPSET)

TARGET_BUILD_VARIANT = os.environ['TARGET_BUILD_VARIANT']
PLATFORM_VERSION = os.environ['PLATFORM_VERSION'] # Release version
PLATFORM_SDK_VERSION = os.environ['PLATFORM_SDK_VERSION'] # API level
SHIPPING_API_LEVEL = os.environ['PRODUCT_SHIPPING_API_LEVEL']
TA_BUILD_FACTORY = os.environ['TA_BUILD_FACTORY']
TA_TARGET_ARCH = "32"
SEC_QUICKBUILD_BUILD_TYPE = os.environ['SEC_QUICKBUILD_BUILD_TYPE']

if 'scorpion' in env['PROC']:
    TA_TARGET_ARCH = "32"
else:
    TA_TARGET_ARCH = "64"
 
WSM_LOGD("TA_TARGET_ARCH : "+TA_TARGET_ARCH)

#------------------------------------------------------------------------------
# COMMON BUILD OPTION
#------------------------------------------------------------------------------
SUPPORT_NEW_TA_BUILD = local_get_env('SUPPORT_NEW_TA_BUILD') # declared inside see_single_ta_sign.sh


#------------------------------------------------------------------------------
# OUT DIR
#------------------------------------------------------------------------------
QSEE_APP_DIR = local_get_env('BSP_QSAPPS_DIR')
QTEE_TAS_SDK_DIR = local_get_env('QTEE_TAS_SDK_DIR')
TZ_ROOT_DIR = local_get_env('TZ_ROOT_DIR')
BUILD_ID = env['SHORT_BUILDPATH']

#------------------------------------------------------------------------------
# WSM Defines
#------------------------------------------------------------------------------
if env['PROC'] == 'scorpion':
    env.Append(CCFLAGS = " -mfpu=neon ")

env.Append(CCFLAGS = ' -DCUST_H=\\"${CUST_H}\\" -DBUILD_TARGET=\\"${BUILD_ID}\\"')

env.Append(CFLAGS = ' -fstack-protector-all -DSWD -DWSM_QSEE -DTA_BUILD -DUSE_SCRYPTO -DENABLE_QSEE_LOGGING -DQSEE ')
env.Append(CCFLAGS = ' -Wno-error -Wno-unused-value -Wno-address-of-packed-member -O0 ')
env.Append(CFLAGS = ' -Dqsee_' + CHIPSET + ' ') # this define is mandatory, inside sources can be found defines like 'qsee_msm8976'

if TARGET_BUILD_VARIANT in ['eng', 'userdebug']:
    WSM_LOGD("MODE : dbg")
    env.Append(CFLAGS = ' -DENABLE_DEBUGGING -D__FILENAME__=__FILE__ -g -DDEBUG ')
else:
    WSM_LOGD("MODE : usr")
    env.Append(CFLAGS = ' -DRELEASE -D__FILENAME__=\"\" ')

#------------------------------------------------------------------------------
# WSM Version and patch
#------------------------------------------------------------------------------
with open("version_ta", 'r') as reader:
    lines = reader.readlines()
CONFIG_BASELINE_CL = lines[1].rstrip()
CONFIG_WSM_VERSION = lines[0].rstrip()

CONFIG_WSM_VERSION_MAJOR, CONFIG_WSM_VERSION_MINOR, CONFIG_WSM_VERSION_PATCH = CONFIG_WSM_VERSION.split('.')

env.Append(CFLAGS = ' -DBASELINE_CL=\\"' + CONFIG_BASELINE_CL + '\\"')
env.Append(CFLAGS = ' -DVERSION_NUMBER=\\"' + CONFIG_WSM_VERSION + '\\"')
env.Append(CFLAGS = ' -DVERSION_NUMBER_MAJOR=' + CONFIG_WSM_VERSION_MAJOR)
env.Append(CFLAGS = ' -DVERSION_NUMBER_MINOR=' + CONFIG_WSM_VERSION_MINOR)
env.Append(CFLAGS = ' -DVERSION_NUMBER_PATCH=' + CONFIG_WSM_VERSION_PATCH)

WSM_LOGD("WSM_CONFIG_VERSION:" + CONFIG_WSM_VERSION_MAJOR + "." + CONFIG_WSM_VERSION_MINOR + "." + CONFIG_WSM_VERSION_PATCH + "." + CONFIG_BASELINE_CL)

#------------------------------------------------------------------------------
# WSM includes
#------------------------------------------------------------------------------
includes = [
    TZ_ROOT_DIR + "/../trustzone_images/core/api/services",
    TZ_ROOT_DIR + "/../trustzone_images/core/api/boot/qfprom",
    TZ_ROOT_DIR + "/../trustzone_images/build/cust",
    TZ_ROOT_DIR + "/../trustzone_images/build/ms",
    QTEE_TAS_SDK_DIR + "/inc/qsee",
    'src',
    'src/common/include',
    'src/common/log/inc',
    'src/common/list/inc',
    'include',
    'src/common/random',
    'src/common/malloc_wrapper/inc',
    'src/common/utilities/inc',
    'src/crypto/src_v2/inc',
    'src/crypto/src/crypto_impl', 
    'src/crypto/src/ta_cmd',
    'src/crypto/src/openssl_impl',  
    'src/common/performance/inc', 
    'src/authentication/inc/private', 
    'src/daemon/inc', 
    'src/common/version', 
    'src/key_manager/inc/ta_cmd', 
    'src/key_manager/inc/private', 
    'src/key_manager/inc', 
    'src/common/pbkdf/ta_cmd', 
    'src/common/pbkdf/inc', 
    'src/authentication/inc', 
    'src/common/crc32', 
    'src/key_storage/inc', 
    'src/crypto/inc', 
    'src/crypto/inc/private', 
    'swd/common/libc_functions/inc',
    'swd/common',
    local_get_env('TZ_SCRYPTO_HEADER_PATH'),
    local_get_env('TZ_PROCA_HEADER_PATH'),
]

#----------------------------------------------------------------------------
# WSM APP_CORE_ENTRY_SOURCES
#----------------------------------------------------------------------------
APP_CORE_ENTRY_SOURCES = [
    'swd/qsee/qseeAgentMain.c',
    'swd/common/libc_functions/src/libc_functions.c',
    'swd/common/libc_functions/src/memmgrs.c',
    'swd/common/custom_so.c',
    'swd/common/deleg_wrap_unwrap.c',
    'swd/common/tl_handler.c',
    'swd/common/tz_proca_handler.c',

    'src/common/crc32/crc32.c',
    'src/common/list/src/wsm_list.c',
    'src/common/list/src/wsm_protected_list.c',
    'src/common/log/src/wsm_log.c',
    'src/common/malloc_wrapper/src/malloc_wrapper.c',
    'src/common/pbkdf/src/pbkdf_hmac_sha256.c',
    'src/common/random/wsm_rand.c',
    'src/common/utilities/src/memory_utilities.c',
    'src/common/utilities/src/string_utilities.c',
    'src/common/utilities/src/utilities.c',
    'src/common/version/version_info.c',

    'src/authentication/src/esap_v1/esap_v1.c',
    'src/authentication/src/esap_v1/ta_esap_v1_cmd.c',
    'src/authentication/src/esap_v1/wsm_v1_auth_utilities.c',
    'src/authentication/src/protocol_v2/protocol_v2.c',
    'src/authentication/src/protocol_v2/ta_protocol_v2_cmd.c',
    'src/authentication/src/protocol_v2/wsm_v2_auth_utilities.c',
    'src/authentication/src/auth_utilities.c',

    'src/crypto/src/crypto_impl/wsm_crypto_common.c',
    'src/crypto/src/crypto_impl/wsm_v1_crypto.c',
    'src/crypto/src/crypto_impl/wsm_v2_crypto.c',
    'src/crypto/src/crypto_impl/wsm_v3_crypto.c',
    'src/crypto/src/openssl_impl/openssl_aes_core.c',
    'src/crypto/src/openssl_impl/wsm_openssl_util.c',
    'src/crypto/src/ta_cmd/cm_ta_cmd.c',
    'src/crypto/src_v2/src/psk.c',
    'src/crypto/src_v2/src/wsm_v1.c',
    'src/crypto/src_v2/src/wsm_v2.c',

    'src/key_manager/src/ta_cmd/km_ta_cmd.c',
    'src/key_manager/src/appskey_type_aes.c',
    'src/key_manager/src/km_impl.c',
    'src/key_storage/src/key_storage.c',
    'src/key_storage/src/key_storage_impl.c',
    'src/key_storage/src/key_storage_wrapper.c',
    'src/key_storage/src/key_storage_eeal.c',
    'src/key_storage/src/key_storage_stub_eeal.c',
]

#------------------------------------------------------------------------------
# Library
#------------------------------------------------------------------------------
privileges = ['default',
              'System',
              'OEMUnwrapKeys',
              'CertValidate',
              'TLMM',
              'SecureDisplay',
              'IntMask',
              'OEMBuf',
             ]

libs = []

if TA_TARGET_ARCH == 32:
    LIBC_PATH = "${MUSL32PATH}/lib/libc.a"
else:
    LIBC_PATH = "${MUSLPATH}/lib/libc.a"
libs.append(env.File(LIBC_PATH.split()))

# Scrypto / PROCA
SCRYPTO_VERSION      = local_get_env('TZ_SCRYPTO_VERSION')
SCRYPTO_LIB_NAME     = local_get_env('TZ_SCRYPTO_LIB'+TA_TARGET_ARCH)
SCRYPTO_IMPRINT      = local_get_env('TZ_SCRYPTO_TOOLS_IMPRINT')
PROCA_ENABLE         = local_get_env('PROCA_ENABLE')
TARGET_SOC           = local_get_env('TARGET_SOC')
SUPPORT_NEW_TA_BUILD = local_get_env('SUPPORT_NEW_TA_BUILD') # declared inside see_single_ta_sign.sh

#Scrypto
libs.append(File(env.SubstRealPath(SCRYPTO_LIB_NAME)))
env.Append(CPPDEFINES=[('CRYPTO_VERSION', '\\"${SCRYPTO_VERSION}\\"')])

#PROCA
if PROCA_ENABLE == 'TRUE':
    WSM_LOGD("PROCA : PROCA library included to WSM TA build")
    env.Append(CFLAGS = ' -DPROCA_FEATURE_ENABLED ')
    PROCA_LIB = local_get_env('TZ_PROCA_LIB'+TA_TARGET_ARCH)
    libs.append(env.File(PROCA_LIB.split()))
    privileges.append('ProcessAuthenticator')

#USE_ALT_ROT_NAME
if SUPPORT_NEW_TA_BUILD == "true":
    WSM_LOGD("USE_ALT_ROT_NAME used")
    env.Append(LINKFLAGS=' -no-threads ') # deterministic 
    env.Append(CFLAGS = ' -DUSE_ALT_ROT_NAME ')

WSM_LOGD("BUILD_ROOT : " + env['BUILD_ROOT'])
WSM_LOGD("INC_ROOT : "+ env['INC_ROOT'])
WSM_LOGD("TZ_SCRYPTO_HEADER_PATH :" + os.environ['TZ_SCRYPTO_HEADER_PATH'])
WSM_LOGD("SCRYPTO_TOOL_IMPRINT : " + os.environ['TZ_SCRYPTO_TOOLS_IMPRINT'])

#------------------------------------------------------------------------------
# Add command to Imprint HMAC
#------------------------------------------------------------------------------
WSM_ELF_PATH = QSEE_APP_DIR + "/build/" + BUILD_ID + "/" + target_name + ".elf"
if CHIPSET in ['bitra', 'sm7250', 'saipan']:
    WSM_ELF_PATH = QSEE_APP_DIR + "/build/" + BUILD_ID + "/scorpion/" + target_name + ".elf"
if CHIPSET in ['sm6115', 'divar', 'lahaina', 'kodiak', 'waipio']:
    WSM_ELF_PATH = QSEE_APP_DIR + "/build/" + target_name + ".elf"

WSM_LOGD("WSM_ELF_PATH : " + WSM_ELF_PATH)

if os.path.exists(os.environ['TOPDIR']):
    RUN_SHELL_COMMAND = "size " + WSM_ELF_PATH + " > " + os.environ['TOPDIR'] + "/android/" + target_name + "_elf.out"
    env.Append(LINKCOM = " && ")
    env.Append(LINKCOM = RUN_SHELL_COMMAND)

WSM_RUN_FIPS_TOOLS_COMMAND = SCRYPTO_IMPRINT + " " + WSM_ELF_PATH

env.Append(LINKCOM = " && ")
env.Append(LINKCOM = WSM_RUN_FIPS_TOOLS_COMMAND)
env.Replace(WSM_RUN_FIPS_TOOLS_COMMAND = SCRYPTO_IMPRINT + " " + WSM_ELF_PATH)

#-------------------------------------------------------------------------------
# Add metadata to image
#-------------------------------------------------------------------------------
md = {
    'appName': target_name,
    'privileges': privileges,
}

if 'scorpion' in env['PROC']:
    md['memoryType'] = 'Unprotected'

try:
    wsm_units = env.SecureAppBuilder(
        sources = [ APP_CORE_ENTRY_SOURCES ],
        includes = includes,
        metadata = md,
        image = target_name,
        user_libs = libs,
        heap_size = '0x10000',
    )
except:
    md['heapSize'] = 0x13000
    wsm_units = env.SecureAppBuilder(
        sources = [ APP_CORE_ENTRY_SOURCES ],
        includes = includes,
        metadata = md,
        image = target_name,
        user_libs = libs,
    )

op = env.Alias(target_name, wsm_units)
Return('wsm_units')
