#/*
# * FreeRTOS Kernel V10.3.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.
# *
# * http://www.FreeRTOS.org
# * http://aws.amazon.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()
