# Copyright (c) 2022-2026 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 logging
import os
import shlex
from enum import Enum, auto

from runner.runner import Runner

from .builder import Builder, BuilderOutput, OutDirLock, lock_output_dir

log = logging.getLogger(__name__)


class TelinkLogLevel(Enum):
    DEFAULT = auto()  # default everything
    ALL = auto()  # enable all logging
    PROGRESS = auto()  # progress and above
    ERROR = auto()  # error and above
    NONE = auto()  # no chip_logging at all


class TelinkApp(Enum):
    AIR_QUALITY_SENSOR = auto()
    ALL_CLUSTERS = auto()
    ALL_CLUSTERS_MINIMAL = auto()
    ALL_DEVICES = auto()
    BRIDGE = auto()
    CONTACT_SENSOR = auto()
    LIGHT = auto()
    SWITCH = auto()
    LOCK = auto()
    OTA_REQUESTOR = auto()
    PUMP = auto()
    PUMP_CONTROLLER = auto()
    SHELL = auto()
    SMOKE_CO_ALARM = auto()
    TEMPERATURE_MEASUREMENT = auto()
    THERMOSTAT = auto()
    WINDOW_COVERING = auto()

    def ExampleName(self):
        if self == TelinkApp.AIR_QUALITY_SENSOR:
            return 'air-quality-sensor-app'
        if self == TelinkApp.ALL_CLUSTERS:
            return 'all-clusters-app'
        if self == TelinkApp.ALL_CLUSTERS_MINIMAL:
            return 'all-clusters-minimal-app'
        if self == TelinkApp.ALL_DEVICES:
            return 'all-devices-app'
        if self == TelinkApp.BRIDGE:
            return 'bridge-app'
        if self == TelinkApp.CONTACT_SENSOR:
            return 'contact-sensor-app'
        if self == TelinkApp.LIGHT:
            return 'lighting-app'
        if self == TelinkApp.SWITCH:
            return 'light-switch-app'
        if self == TelinkApp.LOCK:
            return 'lock-app'
        if self == TelinkApp.OTA_REQUESTOR:
            return 'ota-requestor-app'
        if self == TelinkApp.PUMP:
            return 'pump-app'
        if self == TelinkApp.PUMP_CONTROLLER:
            return 'pump-controller-app'
        if self == TelinkApp.SHELL:
            return 'shell'
        if self == TelinkApp.SMOKE_CO_ALARM:
            return 'smoke-co-alarm-app'
        if self == TelinkApp.TEMPERATURE_MEASUREMENT:
            return 'temperature-measurement-app'
        if self == TelinkApp.THERMOSTAT:
            return 'thermostat'
        if self == TelinkApp.WINDOW_COVERING:
            return 'window-app'
        raise Exception('Unknown app type: %r' % self)

    def AppNamePrefix(self):
        if self == TelinkApp.AIR_QUALITY_SENSOR:
            return 'chip-telink-air-quality-sensor-example'
        if self == TelinkApp.ALL_CLUSTERS:
            return 'chip-telink-all-clusters-example'
        if self == TelinkApp.ALL_CLUSTERS_MINIMAL:
            return 'chip-telink-all-clusters-minimal-example'
        if self == TelinkApp.ALL_DEVICES:
            return 'all-devices-app'
        if self == TelinkApp.BRIDGE:
            return 'chip-telink-bridge-example'
        if self == TelinkApp.CONTACT_SENSOR:
            return 'chip-telink-contact-sensor-example'
        if self == TelinkApp.LIGHT:
            return 'chip-telink-lighting-example'
        if self == TelinkApp.SWITCH:
            return 'chip-telink-light-switch-example'
        if self == TelinkApp.LOCK:
            return 'chip-telink-lock-example'
        if self == TelinkApp.OTA_REQUESTOR:
            return 'chip-telink-ota-requestor-example'
        if self == TelinkApp.PUMP:
            return 'chip-telink-pump-example'
        if self == TelinkApp.PUMP_CONTROLLER:
            return 'chip-telink-pump-controller-example'
        if self == TelinkApp.RESOURCE_MONITORING:
            return 'chip-telink-resource-monitoring-example'
        if self == TelinkApp.SHELL:
            return 'chip-telink-shell-example'
        if self == TelinkApp.SMOKE_CO_ALARM:
            return 'chip-telink-smoke-co-alarm-example'
        if self == TelinkApp.TEMPERATURE_MEASUREMENT:
            return 'chip-telink-temperature-measurement-example'
        if self == TelinkApp.THERMOSTAT:
            return 'chip-telink-thermostat-example'
        if self == TelinkApp.WINDOW_COVERING:
            return 'chip-telink-window-example'
        raise Exception('Unknown app type: %r' % self)


class TelinkBoard(Enum):
    TLRS9118BDK40D = auto()
    TLSR9518ADK80D = auto()
    TLSR9528A = auto()
    TLSR9528A_RETENTION = auto()
    TL3218X = auto()
    TL3218X_ML3M = auto()
    TL3218X_RETENTION = auto()
    TL7218X = auto()
    TL7218X_ML7G = auto()
    TL7218X_ML7M = auto()
    TL7218X_RETENTION = auto()

    def GnArgName(self):
        if self == TelinkBoard.TLRS9118BDK40D:
            return 'tlsr9118bdk40d'
        if self == TelinkBoard.TLSR9518ADK80D:
            return 'tlsr9518adk80d'
        if self == TelinkBoard.TLSR9528A:
            return 'tlsr9528a'
        if self == TelinkBoard.TLSR9528A_RETENTION:
            return 'tlsr9528a_retention'
        if self == TelinkBoard.TL3218X:
            return 'tl3218x'
        if self == TelinkBoard.TL3218X_ML3M:
            return 'tl3218x_ml3m'
        if self == TelinkBoard.TL3218X_RETENTION:
            return 'tl3218x_retention'
        if self == TelinkBoard.TL7218X:
            return 'tl7218x'
        if self == TelinkBoard.TL7218X_ML7G:
            return 'tl7218x_ml7g'
        if self == TelinkBoard.TL7218X_ML7M:
            return 'tl7218x_ml7m'
        if self == TelinkBoard.TL7218X_RETENTION:
            return 'tl7218x_retention'
        raise Exception('Unknown board type: %r' % self)


class TelinkBuilder(Builder):

    def __init__(self,
                 root: str,
                 runner: Runner,
                 output_dir_lock: OutDirLock,
                 app: TelinkApp = TelinkApp,
                 board: TelinkBoard = TelinkBoard,
                 enable_ota: bool = False,
                 enable_dfu_smp: bool = False,
                 enable_shell: bool = False,
                 enable_rpcs: bool = False,
                 enable_factory_data: bool = False,
                 enable_4mb_flash: bool = False,
                 mars_board_config: bool = False,
                 usb_board_config: bool = False,
                 compress_lzma_config: bool = False,
                 thread_analyzer_config: bool = False,
                 precompiled_ot_config: bool = False,
                 tflm_config: bool = False,
                 chip_enable_nfc_onboarding_payload: bool = False,
                 log_level: TelinkLogLevel = TelinkLogLevel.DEFAULT,
                 all_devices_enabled_devices=None,
                 ):
        super().__init__(root, runner, output_dir_lock)
        self.app = app
        self.board = board
        self.enable_ota = enable_ota
        self.enable_dfu_smp = enable_dfu_smp
        self.enable_shell = enable_shell
        self.enable_rpcs = enable_rpcs
        self.enable_factory_data = enable_factory_data
        self.enable_4mb_flash = enable_4mb_flash
        self.mars_board_config = mars_board_config
        self.usb_board_config = usb_board_config
        self.compress_lzma_config = compress_lzma_config
        self.thread_analyzer_config = thread_analyzer_config
        self.precompiled_ot_config = precompiled_ot_config
        self.tflm_config = tflm_config
        self.chip_enable_nfc_onboarding_payload = chip_enable_nfc_onboarding_payload
        self.log_level = log_level
        self.all_devices_enabled_devices = all_devices_enabled_devices or []

    def get_cmd_prefixes(self):
        if not self._runner.dry_run:
            # Zephyr base
            if 'TELINK_ZEPHYR_BASE' not in os.environ:
                raise Exception("Telink builds require TELINK_ZEPHYR_BASE")

        cmd = 'export ZEPHYR_TOOLCHAIN_VARIANT=zephyr\n'
        cmd += 'export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE"\n'

        if 'TELINK_ZEPHYR_SDK_DIR' in os.environ:
            cmd += 'export ZEPHYR_SDK_INSTALL_DIR="$TELINK_ZEPHYR_SDK_DIR"\n'

        return cmd

    @lock_output_dir
    def generate(self):
        os.makedirs(self.output_dir, exist_ok=True)

        flags = []
        if self.enable_ota:
            flags.append("-DCONFIG_CHIP_OTA_REQUESTOR=y")

        if self.enable_dfu_smp:
            flags.append("-DCONFIG_CHIP_DFU_OVER_BT_SMP=y -DCONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=y")

        if self.enable_shell:
            flags.append("-DCONFIG_CHIP_LIB_SHELL=y")

        if self.enable_rpcs:
            flags.append("-DOVERLAY_CONFIG=rpc.overlay")

        if self.enable_factory_data:
            flags.append("-DCONFIG_CHIP_FACTORY_DATA=y -DCONFIG_CHIP_FACTORY_DATA_BUILD=y -DCONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=y")

        if self.enable_4mb_flash:
            flags.append("-DFLASH_SIZE=4m")

        if self.mars_board_config:
            flags.append("-DTLNK_MARS_BOARD=y")

        if self.usb_board_config:
            flags.append("-DTLNK_USB_DONGLE=y")

        if self.compress_lzma_config:
            flags.append("-DCONFIG_COMPRESS_LZMA=y")

        if self.chip_enable_nfc_onboarding_payload:
            flags.append("-DCONFIG_CHIP_NFC_ONBOARDING_PAYLOAD=y")

        if self.thread_analyzer_config:
            flags.append("-DCONFIG_THREAD_ANALYZER=y")

        if self.precompiled_ot_config:
            flags.append("-DCONFIG_OPENTHREAD_TELINK_LIBRARY=y -DCONFIG_LOG_MODE_DEFERRED=y")

        if self.tflm_config:
            flags.append("-DCONFIG_TFLM_FEATURE=y")

        if self.options.pregen_dir:
            flags.append(f"-DCHIP_CODEGEN_PREGEN_DIR={shlex.quote(self.options.pregen_dir)}")

        if self.all_devices_enabled_devices:
            flags.append(f"-DALL_DEVICES_ENABLED_DEVICES={shlex.quote(';'.join(self.all_devices_enabled_devices))}")

        if self.log_level == TelinkLogLevel.DEFAULT:
            pass
        elif self.log_level == TelinkLogLevel.ALL:
            flags.append("-DTLNK_LOG_LEVEL=all")
        elif self.log_level == TelinkLogLevel.PROGRESS:
            flags.append("-DTLNK_LOG_LEVEL=progress")
        elif self.log_level == TelinkLogLevel.ERROR:
            flags.append("-DTLNK_LOG_LEVEL=error")
        elif self.log_level == TelinkLogLevel.NONE:
            flags.append("-DTLNK_LOG_LEVEL=none")
        else:
            raise Exception("Unknown log level: %r" % self.log_level)

        build_flags = " -- " + " ".join(flags) if len(flags) > 0 else ""

        cmd = self.get_cmd_prefixes()
        cmd += '\nsource "$ZEPHYR_BASE/zephyr-env.sh";'

        cmd += '\nwest build --cmake-only -d {outdir} -b {board} {sourcedir}{build_flags}\n'.format(
            outdir=shlex.quote(self.output_dir),
            board=self.board.GnArgName(),
            sourcedir=shlex.quote(os.path.join(self.root, 'examples', self.app.ExampleName(), 'telink')),
            build_flags=build_flags).strip()

        self._Execute(['bash', '-c', cmd],
                      title='Generating ' + self.identifier)

    @lock_output_dir
    def _build(self):
        log.info('Compiling Telink at %s', self.output_dir)

        cmd = self.get_cmd_prefixes() + ("ninja -C %s" % self.output_dir)

        if self.ninja_jobs is not None:
            cmd += " -j%s" % str(self.ninja_jobs)

        self._Execute(['bash', '-c', cmd], title='Building ' + self.identifier)

    def _AllDevicesOutputName(self):
        """Return the binary base name produced by the all-devices-app build."""
        if self.all_devices_enabled_devices:
            return 'example-device-app'
        return 'all-devices-app'

    @lock_output_dir
    def build_outputs(self):
        app_name = self._AllDevicesOutputName() if self.app == TelinkApp.ALL_DEVICES else self.app.AppNamePrefix()
        yield BuilderOutput(
            os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'),
            f'{app_name}.elf')
        if self.options.enable_link_map_file:
            yield BuilderOutput(
                os.path.join(self.output_dir, 'zephyr', 'zephyr.map'),
                f'{app_name}.map')
