#!/usr/bin/env python3

# Copyright (c) 2020 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 hashlib
import json
import optparse
import os
import shutil
import sys
import tarfile
import textwrap
from typing import Any, Dict, Sequence

import yaml
import re

import constants
import stateful_shell
from sample_app_util import zap_file_parser

TermColors = constants.TermColors

shell = stateful_shell.StatefulShell()

_CHEF_SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
_REPO_BASE_PATH = os.path.join(_CHEF_SCRIPT_PATH, "../../")
_DEVICE_FOLDER = os.path.join(_CHEF_SCRIPT_PATH, "devices")
_DEVICE_LIST = [file[:-4]
                for file in os.listdir(_DEVICE_FOLDER) if file.endswith(".zap")]
_CICD_CONFIG_FILE_NAME = os.path.join(_CHEF_SCRIPT_PATH, "cicd_config.json")
_CD_STAGING_DIR = os.path.join(_CHEF_SCRIPT_PATH, "staging")

gen_dir = ""  # Filled in after sample app type is read from args.


def splash() -> None:
    splashText = textwrap.dedent(
        f"""\
        {TermColors.STRBOLD}{TermColors.STRYELLOW}
          ______  __    __   _______  _______
         /      ||  |  |  | |   ____||   ____|
        |  ,----'|  |__|  | |  |__   |  |__
        |  |     |   __   | |   __|  |   __|
        |  `----.|  |  |  | |  |____ |  |
         \\______||__|  |__| |_______||__|{TermColors.STRRESET}
        """)
    flush_print(splashText)


def load_config() -> None:
    config = dict()
    config["nrfconnect"] = dict()
    config["esp32"] = dict()
    config["silabs-thread"] = dict()
    config["ameba"] = dict()
    configFile = f"{_CHEF_SCRIPT_PATH}/config.yaml"
    if (os.path.exists(configFile)):
        configStream = open(configFile, 'r')
        config = yaml.load(configStream, Loader=yaml.SafeLoader)
        configStream.close()
    else:
        flush_print("Running for the first time and configuring config.yaml. " +
                    "Change this configuration file to include correct configuration " +
                    "for the vendor's SDK")
        configStream = open(configFile, 'w')
        config["nrfconnect"]["ZEPHYR_BASE"] = os.environ.get('ZEPHYR_BASE')
        config["nrfconnect"]["TTY"] = None
        config["esp32"]["IDF_PATH"] = os.environ.get('IDF_PATH')
        config["esp32"]["TTY"] = None
        config["silabs-thread"]["GECKO_SDK"] = f"{_REPO_BASE_PATH}third_party/efr32_sdk/repo"
        config["silabs-thread"]["TTY"] = None
        config["silabs-thread"]["CU"] = None
        config["silabs-thread"]["SILABS_BOARD"] = None
        config["ameba"]["AMEBA_SDK"] = None
        config["ameba"]["MATTER_SDK"] = None
        config["ameba"]["MODEL"] = 'D'
        config["ameba"]["TTY"] = None

        flush_print(yaml.dump(config))
        yaml.dump(config, configStream)
        configStream.close()

    return config


def check_python_version() -> None:
    if sys.version_info[0] < 3:
        flush_print('Must use Python 3. Current version is ' +
                    str(sys.version_info[0]))
        exit(1)


def load_cicd_config() -> Dict[str, Any]:
    with open(_CICD_CONFIG_FILE_NAME) as config_file:
        config = json.loads(config_file.read())
    return config


def flush_print(
        to_print: str,
        with_border: bool = False) -> None:
    """Prints and flushes stdout buffer.

    Args:
        to_print: The string to print.
        with_border: Add boarder above and below to_print.
    """
    if with_border:
        border = ('-' * len(to_print)) + '\n'
        to_print = f"{border}{to_print}\n{border}"
    print(to_print, flush=True)


def unwrap_cmd(cmd: str) -> str:
    """Dedent and replace new line with space."""
    return textwrap.dedent(cmd).replace("\n", " ")


def bundle(platform: str, device_name: str) -> None:
    """Filters files from the build output folder for CD.
    Clears _CD_STAGING_DIR.
    Calls bundle_{platform}(device_name).
    exit(1) for missing bundle_{platform}.
    Adds .matter files into _CD_STAGING_DIR.
    Generates metadata for device in _CD_STAGING_DIR.

    Args:
        platform: The platform to bundle.
        device_name: The example to bundle.
    """
    bundler_name = f"bundle_{platform}"
    matter_file = f"{device_name}.matter"
    zap_file = os.path.join(_DEVICE_FOLDER, f"{device_name}.zap")
    flush_print(f"Bundling {platform}", with_border=True)
    flush_print(f"Cleaning {_CD_STAGING_DIR}")
    shutil.rmtree(_CD_STAGING_DIR, ignore_errors=True)
    os.mkdir(_CD_STAGING_DIR)
    flush_print(f"Checking for {bundler_name}")
    chef_module = sys.modules[__name__]
    if hasattr(chef_module, bundler_name):
        flush_print(f"Found {bundler_name}")
        bundler = getattr(chef_module, bundler_name)
        bundler(device_name)
    else:
        flush_print(f"No bundle function for {platform}!")
        exit(1)
    flush_print(f"Copying {matter_file}")
    src_item = os.path.join(_DEVICE_FOLDER,
                            matter_file)
    dest_item = os.path.join(_CD_STAGING_DIR, matter_file)
    shutil.copy(src_item, dest_item)
    flush_print(f"Generating metadata for {device_name}")
    metadata_file = zap_file_parser.generate_hash_metadata_file(zap_file)
    metadata_dest = os.path.join(_CD_STAGING_DIR,
                                 os.path.basename(metadata_file))
    shutil.copy(metadata_file, metadata_dest)


#
# Per-platform bundle functions
#


def bundle_linux(device_name: str) -> None:
    linux_root = os.path.join(_CHEF_SCRIPT_PATH,
                              "linux",
                              "out")
    map_file_name = f"{device_name}.map"
    src_item = os.path.join(linux_root, device_name)
    dest_item = os.path.join(_CD_STAGING_DIR, device_name)
    shutil.copy(src_item, dest_item)
    src_item = os.path.join(linux_root, map_file_name)
    dest_item = os.path.join(_CD_STAGING_DIR, map_file_name)
    shutil.copy(src_item, dest_item)


def bundle_nrfconnect(device_name: str) -> None:
    zephyr_exts = ["elf", "map", "hex"]
    script_files = ["firmware_utils.py",
                    "nrfconnect_firmware_utils.py"]
    nrf_root = os.path.join(_CHEF_SCRIPT_PATH,
                            "nrfconnect",
                            "build",
                            "zephyr")
    scripts_root = os.path.join(_REPO_BASE_PATH,
                                "scripts",
                                "flashing")
    gen_script_path = os.path.join(scripts_root,
                                   "gen_flashing_script.py")
    sub_dir = os.path.join(_CD_STAGING_DIR, device_name)
    os.mkdir(sub_dir)
    for zephyr_ext in zephyr_exts:
        input_base = f"zephyr.{zephyr_ext}"
        output_base = f"{device_name}.{zephyr_ext}"
        src_item = os.path.join(nrf_root, input_base)
        if zephyr_ext == "hex":
            dest_item = os.path.join(sub_dir, output_base)
        else:
            dest_item = os.path.join(_CD_STAGING_DIR, output_base)
        shutil.copy(src_item, dest_item)
    for script_file in script_files:
        src_item = os.path.join(scripts_root, script_file)
        dest_item = os.path.join(sub_dir, script_file)
        shutil.copy(src_item, dest_item)
    shell.run_cmd(f"cd {sub_dir}")
    command = f"""\
    python3 {gen_script_path} nrfconnect
    --output {device_name}.flash.py
    --application {device_name}.hex"""
    shell.run_cmd(unwrap_cmd(command))


def bundle_esp32(device_name: str) -> None:
    """Reference example for bundle_{platform}
    functions, which should copy/move files from a build
    output dir into _CD_STAGING_DIR to be archived.

    Args:
        device_name: The device to bundle.
    """
    esp_root = os.path.join(_CHEF_SCRIPT_PATH,
                            "esp32",
                            "build")
    manifest_file = os.path.join(esp_root,
                                 "chip-shell.flashbundle.txt")
    with open(manifest_file) as manifest:
        for item in manifest:
            item = item.strip()
            src_item = os.path.join(esp_root, item)
            dest_item = os.path.join(_CD_STAGING_DIR, item)
            os.makedirs(os.path.dirname(dest_item), exist_ok=True)
            shutil.copy(src_item, dest_item)


def main() -> int:

    check_python_version()
    config = load_config()
    cicd_config = load_cicd_config()

    #
    # Build environment switches
    #

    if sys.platform == "win32":
        flush_print(
            'Windows is currently not supported. Use Linux or MacOS platforms')
        exit(1)

    #
    # Arguments parser
    #

    deviceTypes = "\n  ".join(_DEVICE_LIST)

    usage = textwrap.dedent(f"""\
        usage: chef.py [options]

        Platforms:
            nrfconnect
            esp32
            linux
            silabs-thread
            ameba

        Device Types:
            {deviceTypes}

        Notes:
        - Whenever you change a device type, make sure to also use options -zbe
        - Be careful if you have more than one device connected. The script assumes you have only one device connected and might flash the wrong one\
        """)
    parser = optparse.OptionParser(usage=usage)

    parser.add_option("-u", "--update_toolchain", help="updates toolchain & installs zap",
                      action="store_true", dest="do_update_toolchain")
    parser.add_option("-b", "--build", help="builds",
                      action="store_true", dest="do_build")
    parser.add_option("-c", "--clean", help="clean build. Only valid if also building",
                      action="store_true", dest="do_clean")
    parser.add_option("-f", "--flash", help="flashes device",
                      action="store_true", dest="do_flash")
    parser.add_option("-e", "--erase", help="erases flash before flashing. Only valid if also flashing",
                      action="store_true", dest="do_erase")
    parser.add_option("-i", "--terminal", help="opens terminal to interact with with device",
                      action="store_true", dest="do_interact")
    parser.add_option("-m", "--menuconfig", help="runs menuconfig on platforms that support it",
                      action="store_true", dest="do_menuconfig")
    parser.add_option("-z", "--zap", help="runs zap to generate data model & interaction model artifacts",
                      action="store_true", dest="do_run_zap")
    parser.add_option("-g", "--zapgui", help="runs zap GUI display to allow editing of data model",
                      action="store_true", dest="do_run_gui")
    parser.add_option("-d", "--device", dest="sample_device_type_name",
                      help="specifies device type. Default is lighting. See info above for supported device types",
                      metavar="TARGET", choices=_DEVICE_LIST)
    parser.add_option("-t", "--target", type='choice',
                      action='store',
                      dest="build_target",
                      help="specifies target platform. Default is esp32. See info below for currently supported target platforms",
                      choices=['nrfconnect', 'esp32',
                               'linux', 'silabs-thread', 'ameba'],
                      metavar="TARGET",
                      default="esp32")
    parser.add_option("-r", "--rpc", help="enables Pigweed RPC interface. Enabling RPC disables the shell interface. Your sdkconfig configurations will be reverted to default. Default is PW RPC off. When enabling or disabling this flag, on the first build force a clean build with -c",
                      action="store_true", dest="do_rpc", default=False)
    parser.add_option("-a", "--automated_test_stamp", help="provide the additional stamp \"branch:commit_id\" as the software version string for automated tests.",
                      action="store_true", dest="do_automated_test_stamp")
    parser.add_option("-v", "--vid", dest="vid", type=int,
                      help="specifies the Vendor ID. Default is 0xFFF1", metavar="VID", default=0xFFF1)
    parser.add_option("-p", "--pid", dest="pid", type=int,
                      help="specifies the Product ID. Default is 0x8000", metavar="PID", default=0x8000)
    parser.add_option("", "--rpc_console", help="Opens PW RPC Console",
                      action="store_true", dest="do_rpc_console")
    parser.add_option("-y", "--tty", help="Enumerated USB tty/serial interface enumerated for your physical device. E.g.: /dev/ACM0",
                      dest="tty", metavar="TTY", default=None)
    parser.add_option("", "--use_zzz", help="Use pre generated output from the ZAP tool found in the zzz_generated folder. Used to decrease execution time of CI/CD jobs",
                      dest="use_zzz", action="store_true")

    # Build CD params.
    parser.add_option("", "--build_all", help="For use in CD only. Builds and bundles all chef examples for the specified platform. Uses --use_zzz. Chef exits after completion.",
                      dest="build_all", action="store_true")
    parser.add_option("", "--dry_run", help="Display list of target builds of the --build_all command without building them.",
                      dest="dry_run", action="store_true")
    parser.add_option("", "--build_exclude", help="For use with --build_all. Build labels to exclude. Accepts a regex pattern. Mutually exclusive with --build_include.",
                      dest="build_exclude")
    parser.add_option("", "--build_include", help="For use with --build_all. Build labels to include. Accepts a regex pattern. Mutually exclusive with --build_exclude.",
                      dest="build_include")
    parser.add_option("-k", "--keep_going", help="For use in CD only. Continues building all sample apps in the event of an error.",
                      dest="keep_going", action="store_true")
    parser.add_option(
        "", "--ci", help="Builds Chef examples defined in cicd_config. Uses --use_zzz. Uses specified target from -t. Chef exits after completion.", dest="ci", action="store_true")
    parser.add_option(
        "", "--enable_ipv4", help="Enable IPv4 mDNS. Only applicable to platforms that can support IPV4 (e.g, Linux, ESP32)",
        action="store_true", default=False)
    parser.add_option(
        "", "--cpu_type", help="CPU type to compile for. Linux only.", choices=["arm64", "arm", "x64"])

    options, _ = parser.parse_args(sys.argv[1:])

    splash()

    #
    # CI
    #

    if options.ci:
        for device_name in cicd_config["ci_allow_list"]:
            if device_name not in _DEVICE_LIST:
                flush_print(
                    f"{device_name} in CICD config but not {_DEVICE_FOLDER}!")
                exit(1)
            if options.build_target == "nrfconnect":
                shell.run_cmd(
                    "export GNUARMEMB_TOOLCHAIN_PATH=\"$PW_ARM_CIPD_INSTALL_DIR\"")
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}")
            command = f"./chef.py -cbr --use_zzz -d {device_name} -t {options.build_target}"
            flush_print(f"Building {command}", with_border=True)
            shell.run_cmd(command)
            bundle(options.build_target, device_name)
        exit(0)

    #
    # CD
    #

    if options.build_all:
        if options.build_include and options.build_exclude:
            flush_print(
                "Error. --build_include and --build_exclude are mutually exclusive options.")
            exit(1)
        flush_print("Building all chef examples")
        archive_prefix = "/workspace/artifacts/"
        archive_suffix = ".tar.gz"
        failed_builds = []
        for device_name in _DEVICE_LIST:
            for platform, label_args in cicd_config["cd_platforms"].items():
                for label, args in label_args.items():
                    archive_name = f"{label}-{device_name}"
                    if options.build_exclude and re.search(options.build_exclude, archive_name):
                        continue
                    elif options.build_include and not re.search(options.build_include, archive_name):
                        continue
                    if options.dry_run:
                        flush_print(archive_name)
                        continue
                    command = f"./chef.py -cbr --use_zzz -d {device_name} -t {platform} "
                    command += " ".join(args)
                    flush_print(f"Building {command}", with_border=True)
                    shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}")
                    shell.run_cmd(
                        "export GNUARMEMB_TOOLCHAIN_PATH=\"$PW_ARM_CIPD_INSTALL_DIR\"")
                    try:
                        shell.run_cmd(command)
                    except RuntimeError as build_fail_error:
                        failed_builds.append((device_name, platform, "build"))
                        flush_print(str(build_fail_error))
                        if not options.keep_going:
                            exit(1)
                        continue
                    try:
                        bundle(platform, device_name)
                    except FileNotFoundError as bundle_fail_error:
                        failed_builds.append((device_name, platform, "bundle"))
                        flush_print(str(bundle_fail_error))
                        if not options.keep_going:
                            exit(1)
                        continue
                    os.makedirs(archive_prefix, exist_ok=True)
                    archive_full_name = archive_prefix + archive_name + archive_suffix
                    flush_print(
                        f"Adding build output to archive {archive_full_name}")
                    if os.path.exists(archive_full_name):
                        os.remove(archive_full_name)
                    with tarfile.open(archive_full_name, "w:gz") as tar:
                        tar.add(_CD_STAGING_DIR, arcname=".")
        if len(failed_builds) == 0:
            flush_print("No build failures", with_border=True)
        else:
            flush_print("Logging build failures", with_border=True)
            for failed_build in failed_builds:
                fail_log = f"""\
                Device: {failed_build[0]},
                Platform: {failed_build[1]},
                Phase: {failed_build[2]}"""
                flush_print(unwrap_cmd(fail_log))
        exit(0)

    #
    # Platform Folder
    #

    flush_print(f"Target is set to {options.sample_device_type_name}")
    global gen_dir
    gen_dir = (
        f"{_CHEF_SCRIPT_PATH}/out/{options.sample_device_type_name}/zap-generated/")

    flush_print("Setting up environment...")
    if options.build_target == "esp32":
        if config['esp32']['IDF_PATH'] is None:
            flush_print(
                'Path for esp32 SDK was not found. Make sure esp32.IDF_PATH is set on your config.yaml file')
            exit(1)
        plat_folder = os.path.normpath(f"{_CHEF_SCRIPT_PATH}/esp32")
        shell.run_cmd(f'source {config["esp32"]["IDF_PATH"]}/export.sh')
    elif options.build_target == "nrfconnect":
        if config['nrfconnect']['ZEPHYR_BASE'] is None:
            flush_print(
                'Path for nrfconnect SDK was not found. Make sure nrfconnect.ZEPHYR_BASE is set on your config.yaml file')
            exit(1)
        plat_folder = os.path.normpath(f"{_CHEF_SCRIPT_PATH}/nrfconnect")
        shell.run_cmd(
            f'source {config["nrfconnect"]["ZEPHYR_BASE"]}/zephyr-env.sh')
        shell.run_cmd("export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb")
    elif options.build_target == "linux":
        pass
    elif options.build_target == "silabs-thread":
        flush_print('Path to gecko sdk is configured within Matter.')
        if 'SILABS_BOARD' not in config['silabs-thread'] or config['silabs-thread']['SILABS_BOARD'] is None:
            flush_print(
                'SILABS_BOARD was not configured. Make sure silabs-thread.SILABS_BOARD is set on your config.yaml file')
            exit(1)
        silabs_board = config['silabs-thread']['SILABS_BOARD']
    elif options.build_target == "ameba":
        if config['ameba']['AMEBA_SDK'] is None:
            flush_print(
                'Path for Ameba SDK was not found. Make sure AMEBA_SDK is set on your config.yaml file')
            exit(1)
        if config['ameba']['MATTER_SDK'] is None:
            flush_print(
                'Path for Matter SDK was not found. Make sure MATTER_SDK is set on your config.yaml file')
            exit(1)
        if (config['ameba']['MODEL'] != 'D' and config['ameba']['MODEL'] != 'Z2'):
            flush_print("Ameba Model is not recognized, please input D or Z2")
            exit(1)
    else:
        flush_print(f"Target {options.build_target} not supported")

    shell.run_cmd(f"source {_REPO_BASE_PATH}/scripts/activate.sh")

    #
    # Toolchain update
    #

    if options.do_update_toolchain:
        if options.build_target == "esp32":
            flush_print("ESP32 toolchain update not supported. Skipping")
        elif options.build_target == "nrfconnect":
            flush_print("Updating toolchain")
            shell.run_cmd(
                f"cd {_REPO_BASE_PATH} && python3 scripts/setup/nrfconnect/update_ncs.py --update")
        elif options.build_target == "silabs-thread":
            flush_print("Silabs-thread toolchain not supported. Skipping")
        elif options.build_target == "linux":
            flush_print("Linux toolchain update not supported. Skipping")
        elif options.build_target == "Ameba":
            flush_print("Ameba toolchain update not supported. Skipping")

    #
    # Clean environment
    #
    if options.do_clean:
        if options.build_target == "esp32":
            shell.run_cmd(f"rm -f {_CHEF_SCRIPT_PATH}/esp32/sdkconfig")
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/esp32")
            shell.run_cmd(f"rm -rf {_CHEF_SCRIPT_PATH}/esp32/build")
            shell.run_cmd("idf.py fullclean")

    #
    # Cluster customization
    #

    if options.do_run_gui:
        flush_print("Starting ZAP GUI editor")
        shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/devices")
        shell.run_cmd(
            f"{_REPO_BASE_PATH}/scripts/tools/zap/run_zaptool.sh {options.sample_device_type_name}.zap")

    if options.do_run_zap:
        flush_print("Running ZAP script to generate artifacts")
        shell.run_cmd(f"rm -rf {gen_dir}")
        shell.run_cmd(f"mkdir -p {gen_dir}")
        shell.run_cmd(
            f"{_REPO_BASE_PATH}/scripts/tools/zap/generate.py {_CHEF_SCRIPT_PATH}/devices/{options.sample_device_type_name}.zap -o {gen_dir}")
        # af-gen-event.h is not generated
        shell.run_cmd(f"touch {gen_dir}/af-gen-event.h")

    #
    # Setup environment
    #
    if options.do_rpc:
        flush_print("RPC PW enabled")
        if options.build_target == "esp32":
            shell.run_cmd(
                f"export SDKCONFIG_DEFAULTS={_CHEF_SCRIPT_PATH}/esp32/sdkconfig_rpc.defaults")
            shell.run_cmd(
                f"[ -f {_CHEF_SCRIPT_PATH}/esp32/sdkconfig ] || cp {_CHEF_SCRIPT_PATH}/esp32/sdkconfig_rpc.defaults {_CHEF_SCRIPT_PATH}/esp32/sdkconfig")
        else:
            flush_print(f"RPC PW on {options.build_target} not supported")

    else:
        flush_print("RPC PW disabled")
        if (options.build_target == "esp32"):
            shell.run_cmd(
                f"export SDKCONFIG_DEFAULTS={_CHEF_SCRIPT_PATH}/esp32/sdkconfig.defaults")
            shell.run_cmd(
                f"[ -f {_CHEF_SCRIPT_PATH}/esp32/sdkconfig ] || cp {_CHEF_SCRIPT_PATH}/esp32/sdkconfig.defaults {_CHEF_SCRIPT_PATH}/esp32/sdkconfig")

    #
    # Menuconfig
    #

    if options.do_menuconfig:
        if options.build_target == "esp32":
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/esp32")
            shell.run_cmd("idf.py menuconfig")
        elif options.build_target == "nrfconnect":
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/nrfconnect")
            shell.run_cmd("west build -t menuconfig")
        elif (options.build_target == "silabs-thread") or (options.build_target == "silabs-wifi"):
            flush_print(
                "Menuconfig not available on Silabs-thread target. Skipping")
        elif options.build_target == "linux":
            flush_print("Menuconfig not available on Linux target. Skipping")
        elif options.build_target == "Ameba":
            flush_print("Menuconfig not available on Ameba target. Skipping")

    #
    # Build
    #

    if options.do_build:
        sw_ver_string = ""

        if options.do_automated_test_stamp:
            branch = ""
            for branch_text in shell.run_cmd("git branch", return_cmd_output=True).split("\n"):
                match_texts = re.findall("\* (.*)", branch_text)
                if match_texts:
                    branch = match_texts[0]
                    break
            commit_id = shell.run_cmd(
                "git rev-parse HEAD", return_cmd_output=True).replace("\n", "")
            sw_ver_string = f"""{branch}:{commit_id}"""
            # 64 bytes space could only contain 63 bytes string + 1 byte EOS.
            if len(sw_ver_string) >= 64:
                truncated_sw_ver_string = f"""{branch[:22]}:{commit_id}"""
                flush_print(
                    f"""Truncate the software version string from \"{sw_ver_string}\" to \"{truncated_sw_ver_string}\" due to 64 bytes limitation""")
                sw_ver_string = truncated_sw_ver_string

        if options.use_zzz:
            flush_print("Using pre-generated ZAP output")
            zzz_dir = os.path.join(_REPO_BASE_PATH,
                                   "zzz_generated",
                                   "chef-"+options.sample_device_type_name,
                                   "zap-generated")
            if not os.path.exists(zzz_dir):
                flush_print(textwrap.dedent(f"""\
                You have specified --use_zzz
                for device {options.sample_device_type_name}
                which does not exist in the cached ZAP output.
                """))
                exit(1)
            shutil.rmtree(gen_dir, ignore_errors=True)
            shutil.copytree(zzz_dir, gen_dir)
        flush_print("Building...")

        flush_print(
            f"Product ID 0x{options.pid:02X} / Vendor ID 0x{options.vid:02X}")
        shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}")

        if (options.build_target == "esp32") or (options.build_target == "nrfconnect") or (options.build_target == "ameba"):
            with open("project_include.cmake", "w") as f:
                f.write(textwrap.dedent(f"""\
                        set(CONFIG_DEVICE_VENDOR_ID {options.vid})
                        set(CONFIG_DEVICE_PRODUCT_ID {options.pid})
                        set(CONFIG_ENABLE_PW_RPC {"1" if options.do_rpc else "0"})
                        set(SAMPLE_NAME {options.sample_device_type_name})
                        set(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING \"{sw_ver_string}\")"""))

        if options.build_target == "esp32":
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/esp32")
            if options.enable_ipv4:
                shell.run_cmd(
                    f"sed -i 's/CONFIG_DISABLE_IPV4=y/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/g' sdkconfig ")
            else:
                shell.run_cmd(
                    f"sed -i 's/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/CONFIG_DISABLE_IPV4=y/g' sdkconfig ")
            shell.run_cmd("idf.py build")
            shell.run_cmd("idf.py build flashing_script")
            shell.run_cmd(
                f"(cd build/ && tar cJvf $(git rev-parse HEAD)-{options.sample_device_type_name}.tar.xz --files-from=chip-shell.flashbundle.txt)")
            shell.run_cmd(
                f"cp build/$(git rev-parse HEAD)-{options.sample_device_type_name}.tar.xz {_CHEF_SCRIPT_PATH}")
        elif options.build_target == "nrfconnect":
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/nrfconnect")
            nrf_build_cmds = ["west build -b nrf52840dk_nrf52840"]
            if options.do_clean:
                nrf_build_cmds.append("-p always")
            if options.do_rpc:
                nrf_build_cmds.append("-- -DOVERLAY_CONFIG=rpc.overlay")
            shell.run_cmd(" ".join(nrf_build_cmds))

        elif options.build_target == "silabs-thread":
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/efr32")
            if options.do_clean:
                shell.run_cmd(f"rm -rf out/{options.sample_device_type_name}")
            efr32_cmd_args = []
            efr32_cmd_args.append(
                f'{_REPO_BASE_PATH}/scripts/examples/gn_efr32_example.sh')
            efr32_cmd_args.append('./')
            efr32_cmd_args.append(f'out/{options.sample_device_type_name}')
            efr32_cmd_args.append(f'{silabs_board}')
            efr32_cmd_args.append(
                f'\'sample_name=\"{options.sample_device_type_name}\"\'')
            if sw_ver_string:
                efr32_cmd_args.append(
                    f'\'chip_device_config_device_software_version_string=\"{sw_ver_string}\"\'')
            efr32_cmd_args.append('enable_openthread_cli=true')
            if options.do_rpc:
                efr32_cmd_args.append('chip_build_libshell=false')
                efr32_cmd_args.append('\'import("//with_pw_rpc.gni")\'')
            else:
                efr32_cmd_args.append('chip_build_libshell=true')
            shell.run_cmd(" ".join(efr32_cmd_args))
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}")

        elif options.build_target == "ameba":
            if config['ameba']['MODEL'] == 'D':
                shell.run_cmd(
                    f"cd {config['ameba']['AMEBA_SDK']}/project/realtek_amebaD_va0_example/GCC-RELEASE")
                if options.do_clean:
                    shell.run_cmd(f"rm -rf out")
                shell.run_cmd(
                    f"./build.sh {config['ameba']['MATTER_SDK']} ninja {config['ameba']['AMEBA_SDK']}/project/realtek_amebaD_va0_example/GCC-RELEASE/out chef-app")
                shell.run_cmd("ninja -C out")
            elif config['ameba']['MODEL'] == 'Z2':
                shell.run_cmd(
                    f"cd {config['ameba']['AMEBA_SDK']}/project/realtek_amebaz2_v0_example/GCC-RELEASE")
                shell.run_cmd("rm -f project_include.mk")
                with open(f"{config['ameba']['AMEBA_SDK']}/project/realtek_amebaz2_v0_example/GCC-RELEASE/project_include.mk", "w") as f:
                    f.write(textwrap.dedent(f"""\
                        SAMPLE_NAME = {options.sample_device_type_name}
                        CHEF_FLAGS =
                        CHEF_FLAGS += -DCONFIG_DEVICE_VENDOR_ID={options.vid}
                        CHEF_FLAGS += -DCONFIG_DEVICE_PRODUCT_ID={options.pid}
                        CHEF_FLAGS += -DCHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING=\"{options.pid}\"
                        """
                                            ))
                if options.do_clean:
                    shell.run_cmd("make clean")
                shell.run_cmd("make chef")
                shell.run_cmd("make is")

        elif options.build_target == "linux":
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/linux")

            linux_args = []
            if options.do_rpc:
                linux_args.append('import("//with_pw_rpc.gni")')
            linux_args.extend([
                'import("//build_overrides/chip.gni")',
                'import("${chip_root}/config/standalone/args.gni")',
                'chip_shell_cmd_server = false',
                'chip_build_libshell = true',
                'chip_config_network_layer_ble = false',
                f'target_defines = ["CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID={options.vid}", "CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID={options.pid}", "CONFIG_ENABLE_PW_RPC={int(options.do_rpc)}"]',
            ])

            uname_resp = shell.run_cmd("uname -m", return_cmd_output=True)
            if "aarch" not in uname_resp and "arm" not in uname_resp:
                if options.cpu_type == "arm64":
                    if "SYSROOT_AARCH64" not in shell.env:
                        flush_print(
                            "SYSROOT_AARCH64 env variable not set. "
                            "AARCH64 toolchain needed for cross-compiling for arm64.")
                        exit(1)
                    shell.env["PKG_CONFIG_PATH"] = (
                        f'{shell.env["SYSROOT_AARCH64"]}/lib/aarch64-linux-gnu/pkgconfig')
                    linux_args.append('target_cpu="arm64"')
                    linux_args.append('is_clang=true')
                    linux_args.append('chip_crypto="mbedtls"')
                    linux_args.append(
                        f'sysroot="{shell.env["SYSROOT_AARCH64"]}"')

                elif options.cpu_type == "arm":
                    if "SYSROOT_ARMHF" not in shell.env:
                        flush_print(
                            "SYSROOT_ARMHF env variable not set. "
                            "ARMHF toolchain needed for cross-compiling for arm.")
                        exit(1)
                    shell.env["PKG_CONFIG_PATH"] = (
                        f'{shell.env["SYSROOT_ARMHF"]}/lib/arm-linux-gnueabihf/pkgconfig')
                    linux_args.append('target_cpu="arm"')
                    linux_args.append('is_clang=true')
                    linux_args.append('chip_crypto="mbedtls"')
                    linux_args.append(
                        f'sysroot="{shell.env["SYSROOT_ARMHF"]}"')

            if options.cpu_type == "x64":
                uname_resp = shell.run_cmd("uname -m", return_cmd_output=True)
                if "x64" not in uname_resp and "x86_64" not in uname_resp:
                    flush_print(
                        f"Unable to cross compile for x64 on {uname_resp}")
                    exit(1)
            if options.enable_ipv4:
                linux_args.append("chip_inet_config_enable_ipv4=true")
            else:
                linux_args.append("chip_inet_config_enable_ipv4=false")

            if sw_ver_string:
                linux_args.append(
                    f'chip_device_config_device_software_version_string = "{sw_ver_string}"')
            with open(f"{_CHEF_SCRIPT_PATH}/linux/args.gni", "w") as f:
                f.write("\n".join(linux_args))
            with open(f"{_CHEF_SCRIPT_PATH}/linux/sample.gni", "w") as f:
                f.write(textwrap.dedent(f"""\
                        sample_zap_file = "{options.sample_device_type_name}.zap"
                        sample_name = "{options.sample_device_type_name}"
                        """))
            if options.do_clean:
                shell.run_cmd(f"rm -rf out")
            shell.run_cmd("gn gen out")
            shell.run_cmd("ninja -C out")

    #
    # Compilation DB TODO
    #

    #
    # Flash
    #

    if options.do_flash:
        flush_print("Flashing target")
        if options.build_target == "esp32":
            if config['esp32']['TTY'] is None:
                flush_print(
                    'The path for the serial enumeration for esp32 is not set. Make sure esp32.TTY is set on your config.yaml file')
                exit(1)
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/esp32")
            if options.do_erase:
                shell.run_cmd(
                    f"idf.py -p {config['esp32']['TTY']} erase-flash")
            shell.run_cmd(f"idf.py -p {config['esp32']['TTY']} flash")
        elif options.build_target == "nrfconnect":
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/nrfconnect")
            if options.do_erase:
                shell.run_cmd("west flash --erase")
            else:
                shell.run_cmd("west flash")
        elif (options.build_target == "silabs-thread") or (options.build_target == "silabs-wifi"):
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/efr32")
            shell.run_cmd(
                f"python3 out/{options.sample_device_type_name}/{silabs_board}/chip-efr32-chef-example.flash.py")

            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}")
        elif (options.build_target == "ameba"):
            if config['ameba']['MODEL'] == 'D':
                shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/ameba")
                shell.run_cmd(
                    f"cd {config['ameba']['AMEBA_SDK']}/tools/AmebaD/Image_Tool_Linux")
                shell.run_cmd(
                    f"{config['ameba']['AMEBA_SDK']}/tools/AmebaD/Image_Tool_Linux/flash.sh {config['ameba']['TTY']} {config['ameba']['AMEBA_SDK']}/project/realtek_amebaD_va0_example/GCC-RELEASE/out", raise_on_returncode=False)
            else:
                shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/ameba")
                shell.run_cmd(
                    f"cd {config['ameba']['AMEBA_SDK']}/tools/AmebaZ2/Image_Tool_Linux")
                shell.run_cmd(
                    f"{config['ameba']['AMEBA_SDK']}/tools/AmebaZ2/Image_Tool_Linux/flash.sh {config['ameba']['TTY']} {config['ameba']['AMEBA_SDK']}/project/realtek_amebaz2_v0_example/GCC-RELEASE/application_is/Debug/bin", raise_on_returncode=False)

    #
    # Terminal interaction
    #

    if options.do_interact:
        flush_print("Starting terminal...")
        if options.build_target == "esp32":
            if config['esp32']['TTY'] is None:
                flush_print(
                    'The path for the serial enumeration for esp32 is not set. Make sure esp32.TTY is set on your config.yaml file')
                exit(1)
            shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/esp32")
            shell.run_cmd(f"idf.py -p {config['esp32']['TTY']} monitor")
        elif options.build_target == "nrfconnect":
            if config['nrfconnect']['TTY'] is None:
                flush_print(
                    'The path for the serial enumeration for nordic is not set. Make sure nrfconnect.TTY is set on your config.yaml file')
                exit(1)
            shell.run_cmd("killall screen")
            shell.run_cmd(f"screen {config['nrfconnect']['TTY']} 115200")
        elif (options.build_target == "silabs-thread"):
            if config['silabs-thread']['TTY'] is None:
                flush_print(
                    'The path for the serial enumeration for silabs-thread is not set. Make sure silabs-thread.TTY is set on your config.yaml file')
                exit(1)

            shell.run_cmd("killall screen")
            shell.run_cmd(
                f"screen {config['silabs-thread']['TTY']} 115200 8-N-1")
        elif options.build_target == "linux":
            flush_print(
                f"{_CHEF_SCRIPT_PATH}/linux/out/{options.sample_device_type_name}")
            shell.run_cmd(
                f"{_CHEF_SCRIPT_PATH}/linux/out/{options.sample_device_type_name}")
        elif options.build_target == "ameba":
            if config['ameba']['TTY'] is None:
                flush_print(
                    'The path for the serial enumeration for ameba is not set. Make sure ameba.TTY is set on your config.yaml file')
                exit(1)
            if config['ameba']['MODEL'] == 'D':
                shell.run_cmd("killall screen")
                shell.run_cmd(f"screen {config['ameba']['TTY']} 115200")
            else:
                flush_print("Ameba Z2 image has not been flashed yet")

    #
    # RPC Console
    #
    if options.do_rpc_console:
        if options.build_target == "esp32":
            shell.run_cmd(
                f"python3 -m chip_rpc.console --device {config['esp32']['TTY']}")
        elif (options.build_target == "silabs-thread"):
            if (sys.platform == "linux") or (sys.platform == "linux2"):
                if(config['silabs-thread']['TTY'] is None):
                    flush_print(
                        'The path for the serial enumeration for silabs-thread is not set. Make sure silabs-thread.TTY is set on your config.yaml file')
                    exit(1)
                shell.run_cmd(
                    f"python3 -m chip_rpc.console --device {config['silabs-thread']['TTY']} -b 115200")
            elif sys.platform == "darwin":
                if(config['silabs-thread']['CU'] is None):
                    flush_print(
                        'The path for the serial enumeration for silabs-thread is not set. Make sure silabs-thread.CU is set on your config.yaml file')
                    exit(1)
                shell.run_cmd(
                    f"python3 -m chip_rpc.console --device {config['silabs-thread']['CU']} -b 115200")

    flush_print("Done")
    return 0


if __name__ == '__main__':
    sys.exit(main())
