#!/bin/bash
#
#  Copyright (c) 2023, The OpenThread Authors.
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#  3. Neither the name of the copyright holder nor the
#     names of its contributors may be used to endorse or promote products
#     derived from this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#  POSSIBILITY OF SUCH DAMAGE.
#

set -euo pipefail

# ==============================================================================
# Bash definitions

if [[ -n ${BASH_SOURCE[0]} ]]; then
    script_path="${BASH_SOURCE[0]}"
else
    script_path="$0"
fi
script_dir="$(realpath "$(dirname "${script_path}")")"
repo_dir="$(dirname "${script_dir}")"
sdk_dir="${SISDK_PATH}"

# ==============================================================================
trust_sdk_and_extensions()
{
    # TODO: Figure out a way to skip the trust command if the SDK or extensions are already trusted

    # List of dirs containing SDK extensions to trust
    # NOTE: this list must only contain absolute paths since it will be used to generate symlinks
    extension_dirs=(
        "${repo_dir}"
        "${repo_dir}/wiseconnect"
    )

    set +x
    echo "======================================================================"
    echo "Trusting Simplicity SDK              :'${sdk_dir}':"
    echo "======================================================================"
    set -x

    # Trust the Simplicity SDK submodule
    slc -v 1 signature trust --sdk "${sdk_dir}" -data "${openthread_slc_data}"

    # Ensure SDK extension folder exists
    mkdir -p "${sdk_dir}/extension"

    set +x
    echo ""
    echo ""
    echo "======================================================================"
    echo "extension_dirs = (${extension_dirs[*]})"
    echo "======================================================================"
    set -x

    # Symlink and trust the extensions
    for extension_dir in "${extension_dirs[@]}"; do

        # Locate .slce file
        local slce_file=()
        slce_file=($(find "${extension_dir}/" -maxdepth 1 -name '*.slce'))
        if [ -z "${slce_file}" ]; then
            echo "ERROR: Couldn't find .slce file at '${extension_dir}'"
            continue
        fi

        # Parse extension name
        for file in "${slce_file[@]}"; do
            local extension_name=""
            extension_line=$(grep -m 1 'id: ' "${file}")
            extension_name="${extension_line//id:/}"
            extension_name="${extension_name// /}"
            # Define symlink location
            local extension_symlink="${sdk_dir}/extension/${extension_name}"

            set +x
            echo ""
            echo ""
            echo "======================================================================"
            echo "Trusting extension '${extension_name}'"
            echo "======================================================================"
            set -x

            # Create symlink if it doesn't already exist
            if [ ! -L "${extension_symlink}" ]; then
                ln -s "${extension_dir}" "${extension_symlink}"
            fi

            # Trust the extension
            slc -v 1 signature trust --sdk "${sdk_dir}" -extpath "${extension_symlink}" -data "${openthread_slc_data}"
        done
    done

    ls -alh "${sdk_dir}/extension"
}

generate_mcu_host()
{
    local usage="Usage: generate <.slcp file> <output dir>"
    set -x

    # Set 'force' to 1 to force generation. This will overwrite any existing files
    local force=0

    # Parse flags
    optspec=":fh-:"
    while getopts "$optspec" optchar; do
        case "${optchar}" in
            f)
                force=1
                shift
                ;;
            h)
                echo "${usage}" >&2
                exit 2
                ;;
        esac
    done

    # Check args
    if [ $# -lt 2 ] || [ $# -gt 3 ]; then
        echo "Usage: generate <.slcp file> <output dir> <board>"
        return 1
    fi

    # Define generation variables
    local slcp=${1?A .slcp file is expected as the first argument}
    local project_name=""
    project_line=$(grep 'project_name: ' "${slcp}")
    project_name="${project_line//project_name:/}"
    project_name="${project_name// /}"
    local generation_dir=${2?A generation output dir is expected as the second argument}
    local board=${3?A board is expected as the third argument}
    local build_dir=${OT_CMAKE_BUILD_DIR-"${repo_dir}/build/${board}"}
    local openthread_slc_data=${openthread_slc_data-"${build_dir}/slc/openthread_slc.data"}

    # Skip generation if previously generated
    if [ -d "${generation_dir}" ] && [ ${force} -ne 1 ]; then
        set +x
        echo "======================================================================"
        echo "Skipping generation for '${project_name}'."
        echo "output dir already exists: ${generation_dir}:"
        echo "======================================================================"
        set -x
        exit
    fi

    trust_sdk_and_extensions

    slc -v 1 generate \
        -data "${openthread_slc_data?}" \
        --cache-home "${build_dir}/slc/slcc_components.cache" \
        --sdk="${sdk_dir?}" \
        --clear-cache \
        --project-file="${slcp}" \
        --project-name="${project_name}" \
        --output-type=cmake \
        --no-copy \
        --export-destination="${generation_dir}" \
        --with="${board};wiseconnect3_sdk"
}

cleanup()
{
    # Placeholder for any cleanup tasks
    :
}

trap cleanup EXIT

generate_mcu_host "$@"
