#/*
# * FreeRTOS Kernel <DEVELOPMENT BRANCH>
# * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
# *
# * SPDX-License-Identifier: MIT
# *
# * 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
# *
# */

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()
