#/*
# * FreeRTOS Kernel V10.4.0
# * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
# *
# * Permission is hereby granted, free of charge, to any person obtaining a copy of
# * this software and associated documentation files (the "Software"), to deal in
# * the Software without restriction, including without limitation the rights to
# * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# * the Software, and to permit persons to whom the Software is furnished to do so,
# * subject to the following conditions:
# *
# * The above copyright notice and this permission notice shall be included in all
# * copies or substantial portions of the Software.
# *
# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# *
# * https://www.FreeRTOS.org
# * https://github.com/FreeRTOS
# *
# * 1 tab == 4 spaces!
# */

import os
import shutil

_THIS_FILE_DIRECTORY_ = os.path.dirname(os.path.realpath(__file__))
_FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_)

_COMPILERS_ = ['GCC', 'IAR']
_ARCH_NS_ = ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ']
_ARCH_S_ = ['ARM_CM33', 'ARM_CM23']

_SUPPORTED_CONFIGS_ =   {
                            'GCC' : ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ'],
                            'IAR' : ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ']
                        }

# Files to be complied in the Secure Project
_SECURE_FILE_PATHS_ = [
    os.path.join('secure', 'context'),
    os.path.join('secure', 'context', 'portable', '_COMPILER_ARCH_'),
    os.path.join('secure', 'heap'),
    os.path.join('secure', 'init'),
    os.path.join('secure', 'macros')
]

# Files to be complied in the Non-Secure Project
_NONSECURE_FILE_PATHS_ = [
    'non_secure',
    os.path.join('non_secure', 'portable', '_COMPILER_ARCH_')
]


def is_supported_config(compiler, arch):
    return arch in _SUPPORTED_CONFIGS_[compiler]


def copy_files_in_dir(src_abs_path, dst_abs_path):
    for src_file in os.listdir(src_abs_path):
        src_file_abs_path = os.path.join(src_abs_path, src_file)
        if os.path.isfile(src_file_abs_path) and src_file != 'ReadMe.txt':
            if not os.path.exists(dst_abs_path):
                os.makedirs(dst_abs_path)
            print('Copying {}...'.format(os.path.basename(src_file_abs_path)))
            shutil.copy2(src_file_abs_path, dst_abs_path)


def copy_files_for_compiler_and_arch(compiler, arch, src_paths, dst_path):
    _COMPILER_ARCH_ = os.path.join(compiler, arch)
    for src_path in src_paths:
        src_path_sanitized = src_path.replace('_COMPILER_ARCH_', _COMPILER_ARCH_ )

        src_abs_path = os.path.join(_THIS_FILE_DIRECTORY_, src_path_sanitized)
        dst_abs_path = os.path.join(_FREERTOS_PORTABLE_DIRECTORY_, _COMPILER_ARCH_, dst_path)

        copy_files_in_dir(src_abs_path, dst_abs_path)


def copy_files():
    # Copy Secure Files
    for compiler in _COMPILERS_:
        for arch in _ARCH_S_:
            if is_supported_config(compiler, arch):
                copy_files_for_compiler_and_arch(compiler, arch, _SECURE_FILE_PATHS_, 'secure')

    # Copy Non-Secure Files
    for compiler in _COMPILERS_:
        for arch in _ARCH_NS_:
            if is_supported_config(compiler, arch):
                copy_files_for_compiler_and_arch(compiler, arch, _NONSECURE_FILE_PATHS_, 'non_secure')


def main():
    copy_files()


if __name__ == '__main__':
    main()
