# @file LinuxGccToolChain.py
# Plugin to configures paths for GCC AARCH64/RISCV/LOONGARCH64 Toolchain
##
# This plugin sets environment variables used in tools_def.template to specify the GCC compiler
# for the requested build architecture.
#
# Copyright (c) Microsoft Corporation
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
import os
import logging
from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin
from edk2toolext.environment import shell_environment


class LinuxGccToolChain(IUefiBuildPlugin):

    def do_post_build(self, thebuilder):
        return 0

    def do_pre_build(self, thebuilder):
        self.Logger = logging.getLogger("LinuxGccToolChain")

        #
        # GCC - The only remaining supported GCC toolchain is now "GCC", others have been deprecated then removed.
        #
        if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "GCC":
            # Start with AARACH64 compiler
            ret = self._check_aarch64()
            if ret != 0:
                self.Logger.critical("Failed in check aarch64")
                return ret

            # Check RISCV64 compiler
            ret = self._check_riscv64()
            if ret != 0:
                self.Logger.critical("Failed in check riscv64")
                return ret

            # Check LoongArch64 compiler
            ret = self._check_loongarch64()
            if ret != 0:
                self.Logger.critical("Failed in check loongarch64")
                return ret

        return 0

    def _check_aarch64(self):
        # check to see if full path already configured
        if shell_environment.GetEnvironment().get_shell_var("GCC_AARCH64_PREFIX") is not None:
            self.Logger.info("GCC_AARCH64_PREFIX is already set.")

        else:
            # now check for install dir.  If set then set the Prefix
            install_path = shell_environment.GetEnvironment(
            ).get_shell_var("GCC_AARCH64_INSTALL")
            if install_path is None:
                return 0

            # make PREFIX to align with tools_def.txt
            prefix = os.path.join(install_path, "bin", "aarch64-none-linux-gnu-")
            shell_environment.GetEnvironment().set_shell_var("GCC_AARCH64_PREFIX", prefix)

        # now confirm it exists
        if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC_AARCH64_PREFIX") + "gcc"):
            self.Logger.error(
                "Path for GCC_AARCH64_PREFIX toolchain is invalid")
            return -2

        return 0

    def _check_riscv64(self):
        # now check for install dir.  If set then set the Prefix
        install_path = shell_environment.GetEnvironment(
        ).get_shell_var("GCC_RISCV64_INSTALL")
        if install_path is None:
            return 0

        # check to see if full path already configured
        if shell_environment.GetEnvironment().get_shell_var("GCC_RISCV64_PREFIX") is not None:
            self.Logger.info("GCC_RISCV64_PREFIX is already set.")

        else:
            # make PREFIX to align with tools_def.txt
            prefix = os.path.join(install_path, "bin", "riscv64-unknown-elf-")
            shell_environment.GetEnvironment().set_shell_var("GCC_RISCV64_PREFIX", prefix)

        # now confirm it exists
        if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC_RISCV64_PREFIX") + "gcc"):
            self.Logger.error(
                "Path for GCC_RISCV64_PREFIX toolchain is invalid")
            return -2

        # Check if LD_LIBRARY_PATH is set for the libraries of RISC-V GCC toolchain
        if shell_environment.GetEnvironment().get_shell_var("LD_LIBRARY_PATH") is not None:
            self.Logger.info("LD_LIBRARY_PATH is already set.")

        prefix = os.path.join(install_path, "lib")
        shell_environment.GetEnvironment().set_shell_var("LD_LIBRARY_PATH", prefix)

        return 0

    def _check_loongarch64(self):
        # check to see if full path already configured
        if shell_environment.GetEnvironment().get_shell_var("GCC_LOONGARCH64_PREFIX") is not None:
            self.Logger.info("GCC_LOONGARCH64_PREFIX is already set.")

        else:
            # now check for install dir.  If set then set the Prefix
            install_path = shell_environment.GetEnvironment(
            ).get_shell_var("GCC_LOONGARCH64_INSTALL")
            if install_path is None:
                return 0

            # make PREFIX to align with tools_def.txt
            prefix = os.path.join(install_path, "bin", "loongarch64-unknown-linux-gnu-")
            shell_environment.GetEnvironment().set_shell_var("GCC_LOONGARCH64_PREFIX", prefix)

        # now confirm it exists
        if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC_LOONGARCH64_PREFIX") + "gcc"):
            self.Logger.error(
                "Path for GCC_LOONGARCH64_PREFIX toolchain is invalid")
            return -2

        return 0
