# Copyright (c) 2021 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import glob
import logging
import os
import shlex
import subprocess
from enum import Enum, auto

from .builder import BuilderOutput
from .gn import GnBuilder


class Efr32App(Enum):
    LIGHT = auto()
    LOCK = auto()
    SWITCH = auto()
    WINDOW_COVERING = auto()
    THERMOSTAT = auto()
    PUMP = auto()
    UNIT_TEST = auto()
    AIR_QUALITY_SENSOR = auto()

    def ExampleName(self):
        if self == Efr32App.LIGHT:
            return 'lighting-app'
        elif self == Efr32App.LOCK:
            return 'lock-app'
        elif self == Efr32App.SWITCH:
            return 'light-switch-app'
        elif self == Efr32App.WINDOW_COVERING:
            return 'window-app'
        elif self == Efr32App.THERMOSTAT:
            return 'thermostat'
        elif self == Efr32App.PUMP:
            return 'pump-app'
        elif self == Efr32App.AIR_QUALITY_SENSOR:
            return 'air-quality-sensor-app'
        else:
            raise Exception('Unknown app type: %r' % self)

    def AppNamePrefix(self):
        if self == Efr32App.LIGHT:
            return 'matter-silabs-lighting-example'
        elif self == Efr32App.LOCK:
            return 'matter-silabs-lock-example'
        elif self == Efr32App.SWITCH:
            return 'matter-silabs-light-switch-example'
        elif self == Efr32App.WINDOW_COVERING:
            return 'matter-silabs-window-example'
        elif self == Efr32App.THERMOSTAT:
            return 'matter-silabs-thermostat-example'
        elif self == Efr32App.PUMP:
            return 'matter-silabs-pump-example'
        elif self == Efr32App.UNIT_TEST:
            return 'matter-silabs-device_tests'
        elif self == Efr32App.AIR_QUALITY_SENSOR:
            return 'matter-silabs-air-quality-sensor-example'
        else:
            raise Exception('Unknown app type: %r' % self)

    def FlashBundleName(self):
        if self == Efr32App.LIGHT:
            return 'lighting_app.flashbundle.txt'
        elif self == Efr32App.LOCK:
            return 'lock_app.flashbundle.txt'
        elif self == Efr32App.SWITCH:
            return 'light_switch_app.flashbundle.txt'
        elif self == Efr32App.WINDOW_COVERING:
            return 'window_app.flashbundle.txt'
        elif self == Efr32App.THERMOSTAT:
            return 'thermostat_app.flashbundle.txt'
        elif self == Efr32App.PUMP:
            return 'pump_app.flashbundle.txt'
        elif self == Efr32App.UNIT_TEST:
            return os.path.join('tests', 'efr32_device_tests.flashbundle.txt')
        elif self == Efr32App.AIR_QUALITY_SENSOR:
            return 'air_quality_sensor_app.flashbundle.txt'
        else:
            raise Exception('Unknown app type: %r' % self)

    def BuildRoot(self, root):
        if self == Efr32App.UNIT_TEST:
            return os.path.join(root, 'src', 'test_driver', 'efr32')
        else:
            return os.path.join(root, 'examples', self.ExampleName(), 'silabs')


class Efr32Board(Enum):
    BRD2704B = 1
    BRD4316A = 2
    BRD4317A = 3
    BRD4318A = 4
    BRD4319A = 5
    BRD4186A = 6
    BRD4187A = 7
    BRD2601B = 8
    BRD4187C = 9
    BRD4186C = 10
    BRD4338A = 11
    BRD2703A = 12
    BRD2605A = 13
    BRD4343A = 14

    def GnArgName(self):
        if self == Efr32Board.BRD2704B:
            return 'BRD2704B'
        elif self == Efr32Board.BRD4316A:
            return 'BRD4316A'
        elif self == Efr32Board.BRD4317A:
            return 'BRD4317A'
        elif self == Efr32Board.BRD4318A:
            return 'BRD4318A'
        elif self == Efr32Board.BRD4319A:
            return 'BRD4319A'
        elif self == Efr32Board.BRD4186A:
            return 'BRD4186A'
        elif self == Efr32Board.BRD4187A:
            return 'BRD4187A'
        elif self == Efr32Board.BRD2601B:
            return 'BRD2601B'
        elif self == Efr32Board.BRD4186C:
            return 'BRD4186C'
        elif self == Efr32Board.BRD4187C:
            return 'BRD4187C'
        elif self == Efr32Board.BRD4338A:
            return 'BRD4338A'
        elif self == Efr32Board.BRD2703A:
            return 'BRD2703A'
        elif self == Efr32Board.BRD2605A:
            return 'BRD2605A'
        elif self == Efr32Board.BRD4343A:
            return 'BRD4343A'
        else:
            raise Exception('Unknown board #: %r' % self)


class Efr32Builder(GnBuilder):

    def __init__(self,
                 root,
                 runner,
                 app: Efr32App = Efr32App.LIGHT,
                 board: Efr32Board = Efr32Board.BRD4187C,
                 chip_build_libshell: bool = False,
                 chip_logging: bool = True,
                 chip_openthread_ftd: bool = True,
                 enable_heap_monitoring: bool = False,
                 enable_openthread_cli: bool = True,
                 show_qr_code: bool = False,
                 enable_rpcs: bool = False,
                 enable_ota_requestor: bool = False,
                 enable_icd: bool = False,
                 enable_low_power: bool = False,
                 enable_wifi: bool = False,
                 enable_rs9116: bool = False,
                 enable_wf200: bool = False,
                 enable_917_ncp: bool = False,
                 enable_wifi_ipv4: bool = False,
                 enable_additional_data_advertising: bool = False,
                 enable_ot_lib: bool = False,
                 enable_ot_coap_lib: bool = False,
                 no_version: bool = False,
                 enable_917_soc: bool = False,
                 use_rps_extension: bool = True
                 ):
        super(Efr32Builder, self).__init__(
            root=app.BuildRoot(root),
            runner=runner)
        self.app = app
        self.extra_gn_options = ['silabs_board="%s"' % board.GnArgName()]
        self.dotfile = ''

        if enable_rpcs:
            self.extra_gn_options.append('is_debug=false import("//with_pw_rpc.gni")')

        if enable_ota_requestor:
            self.extra_gn_options.append('chip_enable_ota_requestor=true')

        if enable_icd:
            self.extra_gn_options.append('chip_enable_icd_server=true chip_openthread_ftd=false')

        if enable_low_power:
            self.extra_gn_options.append(
                'chip_build_libshell=false enable_openthread_cli=false show_qr_code=false disable_lcd=true')

        if chip_build_libshell:
            self.extra_gn_options.append('chip_build_libshell=true')

        if chip_logging is False:
            self.extra_gn_options.append('chip_logging=false')

        if chip_openthread_ftd is False:
            self.extra_gn_options.append('chip_openthread_ftd=false')

        if enable_heap_monitoring:
            self.extra_gn_options.append('enable_heap_monitoring=true')

        if enable_openthread_cli is False:
            self.extra_gn_options.append('enable_openthread_cli=false')

        if show_qr_code:
            self.extra_gn_options.append('show_qr_code=true')

        if enable_wifi:
            self.dotfile += self.root + '/build_for_wifi_gnfile.gn'
            if enable_917_soc:
                # Wifi SoC platform
                self.extra_gn_options.append('chip_device_platform=\"SiWx917\"')
            else:
                if enable_rs9116:
                    self.extra_gn_options.append('use_rs9116=true chip_device_platform =\"efr32\"')
                elif enable_wf200:
                    self.extra_gn_options.append('use_wf200=true chip_device_platform =\"efr32\"')
                elif enable_917_ncp:
                    self.extra_gn_options.append('use_SiWx917=true chip_device_platform =\"efr32\"')
                else:
                    raise Exception('Wifi usage: ...-wifi-[rs9116|wf200|siwx917]-...')

        if enable_wifi_ipv4:
            self.extra_gn_options.append('chip_enable_wifi_ipv4=true')

        if enable_additional_data_advertising:
            self.extra_gn_options.append('chip_enable_additional_data_advertising=true chip_enable_rotating_device_id=true')

        if enable_ot_lib:
            self.extra_gn_options.append(
                'use_silabs_thread_lib=true chip_openthread_target="../silabs:ot-efr32-cert" openthread_external_platform=""')

        if enable_ot_coap_lib:
            self.extra_gn_options.append(
                'use_silabs_thread_lib=true chip_openthread_target="../silabs:ot-efr32-cert" '
                'use_thread_coap_lib=true openthread_external_platform=""')

        if not no_version:
            shortCommitSha = subprocess.check_output(
                ['git', 'describe', '--always', '--dirty', '--exclude', '*']).decode('ascii').strip()
            branchName = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).decode('ascii').strip()
            self.extra_gn_options.append(
                'sl_matter_version_str="v1.3-%s-%s"' % (branchName, shortCommitSha))

        if use_rps_extension is False:
            self.extra_gn_options.append('use_rps_extension=false')

        if "GSDK_ROOT" in os.environ:
            # EFR32 SDK is very large. If the SDK path is already known (the
            # case for pre-installed images), use it directly.
            sdk_path = shlex.quote(os.environ['GSDK_ROOT'])
            self.extra_gn_options.append(f"efr32_sdk_root=\"{sdk_path}\"")

        if "GSDK_ROOT" in os.environ and not enable_wifi:
            self.extra_gn_options.append(f"openthread_root=\"{sdk_path}/util/third_party/openthread\"")

        if "WISECONNECT_SDK_ROOT" in os.environ:
            wiseconnect_sdk_path = shlex.quote(os.environ['WISECONNECT_SDK_ROOT'])
            self.extra_gn_options.append(f"wiseconnect_sdk_root=\"{wiseconnect_sdk_path}\"")

        if "WIFI_SDK_ROOT" in os.environ:
            wifi_sdk_path = shlex.quote(os.environ['WIFI_SDK_ROOT'])
            self.extra_gn_options.append(f"wifi_sdk_root=\"{wifi_sdk_path}\"")

    def GnBuildArgs(self):
        return self.extra_gn_options

    def _bundle(self):
        # Only unit-test needs to generate the flashbundle here.  All other examples will generate a flashbundle via the silabs_executable template.
        if self.app == Efr32App.UNIT_TEST:
            flash_bundle_path = os.path.join(self.output_dir, self.app.FlashBundleName())
            logging.info(f'Generating flashbundle {flash_bundle_path}')

            patterns = [
                os.path.join(self.output_dir, "tests", "*.flash.py"),
                os.path.join(self.output_dir, "tests", "*.s37"),
                os.path.join(self.output_dir, "tests", "silabs_firmware_utils.py"),
                os.path.join(self.output_dir, "tests", "firmware_utils.py"),
            ]

            # Generate the list of files by globbing each pattern.
            files = []
            for pattern in patterns:
                files.extend([os.path.basename(x) for x in glob.glob(pattern)])

            # Create the bundle file.
            with open(flash_bundle_path, 'w') as bundle_file:
                bundle_file.write("\n".join(files))

    def build_outputs(self):
        extensions = ["out", "hex"]
        if self.options.enable_link_map_file:
            extensions.append("out.map")

        if self.app == Efr32App.UNIT_TEST:
            # Efr32 unit-test generates the "tests" subdir with a set of files for each individual unit test source.
            for ext in extensions:
                pattern = os.path.join(self.output_dir, "tests", f"*.{ext}")
                for name in [os.path.basename(x) for x in glob.glob(pattern)]:
                    yield BuilderOutput(os.path.join(self.output_dir, "tests", name), name)
        else:
            # All other examples have just one set of files.
            for ext in extensions:
                name = f"{self.app.AppNamePrefix()}.{ext}"
                yield BuilderOutput(os.path.join(self.output_dir, name), name)

        if self.app == Efr32App.UNIT_TEST:
            # Include test runner python wheels
            for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_pw_test_runner_wheels')):
                for file in files:
                    yield BuilderOutput(
                        os.path.join(root, file),
                        os.path.join("chip_pw_test_runner_wheels", file))

    def bundle_outputs(self):
        # If flashbundle creation is enabled, the outputs will include the s37 and flash.py files, plus the two firmware utils scripts that support flash.py.
        # For the unit-test example, there will be a s37 and flash.py file for each unit test source.
        with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f:
            for name in filter(None, [x.strip() for x in f.readlines()]):
                if self.app == Efr32App.UNIT_TEST:
                    sourcepath = os.path.join(self.output_dir, "tests", name)  # Unit tests are in the "tests" subdir.
                else:
                    sourcepath = os.path.join(self.output_dir, name)
                yield BuilderOutput(
                    sourcepath,
                    os.path.join("flashbundle", name))

    def generate(self):
        cmd = [
            'gn', 'gen', '--check', '--fail-on-unused-args',
            '--export-compile-commands',
            '--root=%s' % self.root
        ]
        if self.dotfile:
            cmd += ['--dotfile=%s' % self.dotfile]

        extra_args = self.GnBuildArgs()

        if self.options.pw_command_launcher:
            extra_args.append('pw_command_launcher="%s"' % self.options.pw_command_launcher)

        if self.options.enable_link_map_file:
            extra_args.append('chip_generate_link_map_file=true')

        if self.options.pregen_dir:
            extra_args.append('chip_code_pre_generated_directory="%s"' % self.options.pregen_dir)

        if extra_args:
            cmd += ['--args=%s' % ' '.join(extra_args)]

        cmd += [self.output_dir]

        title = 'Generating ' + self.identifier
        extra_env = self.GnBuildEnv()

        if extra_env:
            # convert the command into a bash command that includes
            # setting environment variables
            cmd = [
                'bash', '-c', '\n' + ' '.join(
                    ['%s="%s" \\\n' % (key, value) for key, value in extra_env.items()] +
                    [shlex.join(cmd)]
                )
            ]

        self._Execute(cmd, title=title)
