#!/usr/bin/env python3

#
# SPDX-License-Identifier: GPL-2.0-only
#

import argparse
import configparser
import copy
import datetime
import functools
import glob
import json
import logging
import os
import shutil
import signal
import string
import subprocess
import sys
import textwrap
import time

__version__ = "2.19.0"

bindir = os.path.abspath(os.path.dirname(__file__))
sys.path[0:0] = [os.path.join(os.path.dirname(bindir), 'lib')]

import bb.msg  # noqa: E402
import bb.process  # noqa: E402
from bb import __version__ as libbb_version # noqa: E402

if __name__ == "__main__":
    if __version__ != libbb_version:
        sys.exit("Bitbake core library version and program version mismatch!")

logger = bb.msg.logger_create('bitbake-setup', sys.stdout)

# These settings can only be set in the global context
GLOBAL_ONLY_SETTINGS = (
    "top-dir-prefix",
    "top-dir-name",
)

def color_enabled() -> bool:
    """
    Our logger has a BBLogFormatter formatter which holds whether color is
    enabled or not. Return this value.
    """
    return logger.handlers[0].formatter.color_enabled

def get_diff_color_param() -> str:
    return "--color=always" if color_enabled() else "--color=never"

def print_configs(prompt: str, choices: list[str], descriptions: list[str] = []):
    """
    Helper function to print a list of choices and align the output.
    Each option name is made bold to stand out, unless color is not enabled in
    our logger.
    """
    if not prompt.endswith(':'):
        prompt += ":"
    logger.plain(prompt)

    if not descriptions:
        descriptions = ["" for _ in choices]

    # maximum size of all choices, for alignment
    cmax = max([len(c) for c in choices]) + 1

    for n, c in enumerate(choices):
        msg = f"{n + 1}. "
        if color_enabled():
            # make it bold
            msg += "\033[1m"
        msg += f"{c:<{cmax}}"
        if color_enabled():
            msg += "\033[0m"
        msg += f" {descriptions[n]}"
        logger.plain(msg)

# If bitbake is from a release tarball or somewhere like pypi where
# updates may not be straightforward, prefer to use the git repo as the
# default registry
def get_default_registry():
    internal_registry = os.path.normpath(os.path.dirname(__file__) + "/../default-registry")
    git_registry = "git://git.openembedded.org/bitbake;protocol=https;branch=master;rev=master"
    if os.path.exists(os.path.dirname(__file__) + "/../.git"):
        return internal_registry
    else:
        return git_registry

def cache_dir(top_dir):
    return os.path.join(top_dir, '.bitbake-setup-cache')

def init_bb_cache(top_dir, settings, args):
    dldir = settings["default"]["dl-dir"]
    bb_cachedir = os.path.join(cache_dir(top_dir), 'bitbake-cache')
    os.makedirs(bb_cachedir, exist_ok=True)

    d = bb.data.init()
    d.setVar("DL_DIR", dldir)
    d.setVar("BB_CACHEDIR", bb_cachedir)
    d.setVar("__BBSRCREV_SEEN", "1")
    if args.no_network:
        d.setVar("BB_SRCREV_POLICY", "cache")
    bb.fetch.fetcher_init(d)
    return d

def save_bb_cache():
    bb.fetch2.fetcher_parse_save()
    bb.fetch2.fetcher_parse_done()

def get_config_name(config):
    suffix = '.conf.json'
    config_file = os.path.basename(config)
    if config_file.endswith(suffix):
        return config_file[:-len(suffix)]
    else:
        raise Exception("Config file {} does not end with {}, please rename the file.".format(config, suffix))

def write_upstream_config(config_dir, config_data):
    with open(os.path.join(config_dir, "config-upstream.json"),'w') as s:
        json.dump(config_data, s, sort_keys=True, indent=4)

def write_sources_fixed_revisions(config_dir, layer_dir, config_data):
    json_path = os.path.join(config_dir, "sources-fixed-revisions.json")
    json_link = os.path.join(layer_dir, "sources-fixed-revisions.json")
    sources = {}
    sources['sources'] = config_data
    with open(os.path.join(config_dir, "sources-fixed-revisions.json"),'w') as s:
        json.dump(sources, s, sort_keys=True, indent=4)
    if not os.path.lexists(json_link):
        os.symlink(os.path.relpath(json_path ,layer_dir), json_link)

def commit_config(config_dir):
    bb.process.run(['git', '-C', config_dir, 'add', '.'])
    bb.process.run(['git', '-C', config_dir, 'commit', '--allow-empty', '--no-verify', '-a', '-m', 'Configuration at ' + time.asctime()])

def _write_layer_list(dest, repodirs):
    layers = []
    for r in repodirs:
        for root, _, files in os.walk(os.path.join(dest,r)):
            if os.path.basename(root) == 'conf' and 'layer.conf' in files:
                layers.append(os.path.relpath(os.path.dirname(root), dest))
    layers_f = os.path.join(dest, ".oe-layers.json")
    with open(layers_f, 'w') as f:
        json.dump({"version":"1.0","layers":layers}, f, sort_keys=True, indent=4)

def add_unique_timestamp_to_path(path):
    timestamp = time.strftime("%Y%m%d%H%M%S")
    path_unique = "{}.{}".format(path, timestamp)
    if os.path.exists(path_unique):
        import itertools
        for i in itertools.count(start=1):
            path_unique = "{}.{}.{}".format(path, timestamp, i)
            if not os.path.exists(path_unique):
                break
    return path_unique

def _get_remotes(r_remote):
    remotes = []

    if 'remotes' not in r_remote and 'uri' not in r_remote:
        raise Exception("Expected key(s): 'remotes', 'uri'")

    if 'remotes' in r_remote:
        for remote in r_remote['remotes']:
            remotes.append(r_remote['remotes'][remote]['uri'])

    if 'uri' in r_remote:
        remotes.append(r_remote['uri'])

    return remotes

def checkout_layers(layers, confdir, layerdir, d, rebase_conflicts_strategy='abort'):
    def _checkout_git_remote(r_remote, repodir, layers_fixed_revisions):
        rev = r_remote['rev']
        branch = r_remote.get('branch', None)

        remotes = _get_remotes(r_remote)

        for remote in remotes:
            prot,host,path,user,pswd,params = bb.fetch.decodeurl(remote)
            fetchuri = bb.fetch.encodeurl(('git',host,path,user,pswd,params))
            logger.plain("    {}".format(r_name))
            if branch:
                src_uri = f"{fetchuri};protocol={prot};rev={rev};branch={branch};destsuffix={repodir}"
            else:
                src_uri = f"{fetchuri};protocol={prot};rev={rev};nobranch=1;destsuffix={repodir}"
            fetcher = bb.fetch.Fetch([src_uri], d)
            repodir_path = os.path.join(layerdir, repodir)
            try:
                do_fetch(fetcher, layerdir)
            except (bb.fetch2.LocalModificationsError, bb.fetch2.RebaseError) as e:
                if rebase_conflicts_strategy != 'backup':
                    e.msg += ("\nUse 'bitbake-setup update --rebase-conflicts-strategy=backup'"
                              " to automatically back up the directory and re-clone from upstream,"
                              " or use 'bitbake-setup init -L %s /path/to/local/checkout'"
                              " to work with a local checkout instead." % r_name)
                    raise
                backup_path = add_unique_timestamp_to_path(repodir_path + '-backup')
                logger.warning(
                    "%s\n"
                    "Renaming %s to %s to preserve your work, then re-cloning from upstream.",
                    e, repodir_path, backup_path)
                os.rename(repodir_path, backup_path)
                fetcher.unpack(layerdir)
            urldata = fetcher.ud[src_uri]
            revision = urldata.revision
            layers_fixed_revisions[r_name]['git-remote']['rev'] = revision

    def _symlink_local(src, dst):
        logger.plain("Making a symbolic link {} pointing to {}".format(dst, src))
        os.symlink(src, dst)

    layers_fixed_revisions = copy.deepcopy(layers)
    repodirs = []
    oesetupbuild = None
    logger.plain("Fetching layer/tool repositories into {}".format(layerdir))
    for r_name in layers:
        r_data = layers[r_name]
        repodir = r_data.get("path", r_name)
        repodirs.append(repodir)

        r_remote = r_data.get('git-remote')
        r_local = r_data.get('local')
        if r_remote and r_local:
            raise Exception("Source {} contains both git-remote and local properties.".format(r_name))

        repodir_path = os.path.join(layerdir, repodir)
        if os.path.lexists(repodir_path):
            if os.path.islink(repodir_path):
                os.remove(repodir_path)
            elif r_local:
                backup_path = add_unique_timestamp_to_path(repodir_path + '-backup')
                logger.warning("""Source {} in {} contains local modifications. Renaming to {} to preserve them.
For local development work it is recommended to clone the needed layers separately and re-initialize using -L option:
bitbake-setup init -L {} /path/to/repo/checkout""".format(
                    r_name, repodir_path, backup_path, r_name))
                os.rename(repodir_path, backup_path)

        if r_remote:
            _checkout_git_remote(r_remote, repodir, layers_fixed_revisions)
        if r_local:
            _symlink_local(os.path.expanduser(r_local["path"]), repodir_path)

        if os.path.exists(os.path.join(layerdir, repodir, 'scripts/oe-setup-build')):
            oesetupbuild = os.path.join(layerdir, repodir, 'scripts/oe-setup-build')
            oeinitbuildenvdir = os.path.join(layerdir, repodir)

    logger.plain("        ")
    _write_layer_list(layerdir, repodirs)

    if oesetupbuild:
        links = {'setup-build': oesetupbuild, 'oe-scripts': os.path.dirname(oesetupbuild), 'oe-init-build-env-dir': oeinitbuildenvdir}
        for link,item in links.items():
            symlink = os.path.join(layerdir, link)
            if os.path.lexists(symlink):
                os.remove(symlink)
            os.symlink(os.path.relpath(item,layerdir),symlink)

    return layers_fixed_revisions

def setup_bitbake_build(bitbake_config, layerdir, setupdir, thisdir, update_bb_conf, init_vscode=False):
    def _setup_build_conf(layers, filerelative_layers, build_conf_dir):
        os.makedirs(build_conf_dir)
        layers_s = []

        for layer in layers:
            layer = os.path.join(layerdir, layer)
            layers_s.append("  {} \\".format(layer))

        for layer in filerelative_layers:
            if thisdir:
                layer = os.path.join(thisdir, layer)
            else:
                raise Exception("Configuration is using bb-layers-file-relative to specify " \
                "a layer path relative to itself. This can be done only " \
                "when the configuration is specified by its path on local " \
                "disk, not when it's in a registry or is fetched over http.")
            layers_s.append("  {} \\".format(layer))

        layers_s = "\n".join(layers_s)
        bblayers_conf = """BBLAYERS ?= " \\
{}
  "
""".format(layers_s)
        with open(os.path.join(build_conf_dir, "bblayers.conf"), 'w') as f:
            f.write(bblayers_conf)

        local_conf = """#
# This file is intended for local configuration tweaks.
#
# If you would like to publish and share changes made to this file,
# it is recommended to put them into a distro config, or to create
# layer fragments from changes made here.
#
"""
        with open(os.path.join(build_conf_dir, "local.conf"), 'w') as f:
            f.write(local_conf)

        with open(os.path.join(build_conf_dir, "templateconf.cfg"), 'w') as f:
            f.write("")

        with open(os.path.join(build_conf_dir, "conf-summary.txt"), 'w') as f:
            f.write(bitbake_config["description"] + "\n")

        with open(os.path.join(build_conf_dir, "conf-notes.txt"), 'w') as f:
            notes = bitbake_config.get("notes")
            if isinstance(notes, list):
                notes = "\n".join(notes)
            f.write(notes + "\n" if notes else "")

    def _make_init_build_env(builddir, oeinitbuildenvdir):
        builddir = os.path.realpath(builddir)
        cmd = 'cd {}\nset {}\n. ./oe-init-build-env\nset --\n'.format(oeinitbuildenvdir, builddir)
        initbuild_in_builddir = os.path.join(builddir, 'init-build-env')

        with open(initbuild_in_builddir, 'w') as f:
            f.write("# init-build-env wrapper created by bitbake-setup\n")
            f.write(cmd + '\n')

    def _prepend_passthrough_to_init_build_env(builddir):
        env = bitbake_config.get("bb-env-passthrough-additions")
        if not env:
            return

        initbuild_in_builddir = os.path.join(builddir, 'init-build-env')
        with open(initbuild_in_builddir) as f:
            content = f.read()

        joined = " \\\n".join(env)
        env = "export BB_ENV_PASSTHROUGH_ADDITIONS=\" \\\n"
        env += "${BB_ENV_PASSTHROUGH_ADDITIONS} \\\n"
        env += joined
        env += '"'

        with open(initbuild_in_builddir, 'w') as f:
            f.write("# environment passthrough added by bitbake-setup\n")
            f.write(env + '\n')
            f.write('\n')
            f.write(content)

    bitbake_builddir = os.path.join(setupdir, "build")
    logger.plain("Setting up bitbake configuration in\n    {}\n".format(bitbake_builddir))

    template = bitbake_config.get("oe-template")
    layers = bitbake_config.get("bb-layers")
    if not template and not layers:
        logger.error("Bitbake configuration does not contain a reference to an OpenEmbedded build template via 'oe-template' or a list of layers via 'bb-layers'; please use oe-setup-build, oe-init-build-env or another mechanism manually to complete the setup.")
        return
    oesetupbuild = os.path.join(layerdir, 'setup-build')
    if template and not os.path.exists(oesetupbuild):
        raise Exception("Cannot complete setting up a bitbake build directory from OpenEmbedded template '{}' as oe-setup-build was not found in any layers; please use oe-init-build-env manually.".format(template))

    bitbake_confdir = os.path.join(bitbake_builddir, 'conf')
    backup_bitbake_confdir = add_unique_timestamp_to_path(os.path.join(bitbake_builddir, 'conf-backup'))
    upstream_bitbake_confdir = add_unique_timestamp_to_path(os.path.join(bitbake_builddir, 'conf-upstream'))

    if os.path.exists(bitbake_confdir):
        os.rename(bitbake_confdir, backup_bitbake_confdir)

    if layers:
        filerelative_layers = bitbake_config.get("bb-layers-file-relative") or []
        _setup_build_conf(layers, filerelative_layers, bitbake_confdir)

    if template:
        bb.process.run([oesetupbuild, "setup", "-c", template, "-b", bitbake_builddir, "--no-shell"])
    else:
        oeinitbuildenvdir = os.path.join(layerdir, 'oe-init-build-env-dir')
        if not os.path.exists(os.path.join(oeinitbuildenvdir, "oe-init-build-env")):
            logger.error("Could not find oe-init-build-env in any of the layers; please use another mechanism to initialize the bitbake environment")
            return
        _make_init_build_env(bitbake_builddir, os.path.realpath(oeinitbuildenvdir))

    _prepend_passthrough_to_init_build_env(bitbake_builddir)

    siteconf_symlink = os.path.join(bitbake_confdir, "site.conf")
    siteconf = os.path.normpath(os.path.join(setupdir, '..', "site.conf"))
    if os.path.lexists(siteconf_symlink):
        os.remove(siteconf_symlink)
    os.symlink(os.path.relpath(siteconf, bitbake_confdir), siteconf_symlink)


    init_script = os.path.join(bitbake_builddir, "init-build-env")
    workspace_file = os.path.join(setupdir, "bitbake.code-workspace")
    shell = "bash"
    # oe-fragments entries can be strings or dicts with 'name'/'description' keys
    oe_fragments = [f["name"] if isinstance(f, dict) else f for f in bitbake_config.get("oe-fragments", [])]
    fragments = oe_fragments + sorted(bitbake_config.get("oe-fragment-choices",{}).values())
    if fragments:
        bb.process.run("{} -c '. {} && bitbake-config-build enable-fragment {}'".format(shell, init_script, " ".join(fragments)))

    if os.path.exists(backup_bitbake_confdir):
        conf_diff = get_diff(backup_bitbake_confdir, bitbake_confdir)
        if not conf_diff:
            logger.plain('New bitbake configuration from upstream is the same as the current one, no need to update it.')
            shutil.rmtree(bitbake_confdir)
            os.rename(backup_bitbake_confdir, bitbake_confdir)
            if init_vscode or os.path.exists(workspace_file):
                configure_vscode(setupdir, layerdir, bitbake_builddir, init_script)
            return

        logger.plain('Upstream bitbake configuration changes were found:')
        logger.plain(conf_diff)

        if update_bb_conf == 'prompt':
            y_or_n = input('Apply these changes to the current configuration? (y/N): ')
            if y_or_n != 'y':
                update_bb_conf = 'no'

        if update_bb_conf == 'no':
            logger.plain('Ignoring upstream bitbake configuration changes')
            logger.plain(f'Leaving the upstream configuration in {upstream_bitbake_confdir}')
            os.rename(bitbake_confdir, upstream_bitbake_confdir)
            os.rename(backup_bitbake_confdir, bitbake_confdir)
            if init_vscode or os.path.exists(workspace_file):
                configure_vscode(setupdir, layerdir, bitbake_builddir, init_script)
            return

        logger.plain('Applying upstream bitbake configuration changes')
        logger.plain(f'Leaving the previous configuration in {backup_bitbake_confdir}')

    fragment_note = "Run 'bitbake-config-build enable-fragment <fragment-name>' to enable additional fragments or replace built-in ones (e.g. machine/<name> or distro/<name> to change MACHINE or DISTRO)."

    readme_extra = ""
    if init_vscode:
        readme_extra = "\nTo edit the code in VSCode, open the workspace: code {}\n".format(workspace_file)

    readme = """{}\n\nAdditional information is in {} and {}\n
Source the environment using '. {}' to run builds from the command line.\n
{}\n
The bitbake configuration files (local.conf, bblayers.conf and more) can be found in {}/conf
{}""".format(
        bitbake_config["description"],
        os.path.join(bitbake_builddir,'conf/conf-summary.txt'),
        os.path.join(bitbake_builddir,'conf/conf-notes.txt'),
        init_script,
        fragment_note,
        bitbake_builddir,
        readme_extra
        )
    readme_file = os.path.join(bitbake_builddir, "README")
    with open(readme_file, 'w') as f:
        f.write(readme)

    logger.plain("This bitbake configuration provides:\n    {}\n".format(bitbake_config["description"]))
    logger.plain("Usage instructions and additional information are in\n     {}\n".format(readme_file))
    logger.plain("To run builds, source the environment using\n    . {}\n".format(init_script))
    logger.plain("{}\n".format(fragment_note))
    logger.plain("The bitbake configuration files (local.conf, bblayers.conf and more) can be found in\n    {}/conf\n".format(bitbake_builddir))
    if init_vscode:
        logger.plain("To edit the code in VSCode, open the workspace:\n    code {}\n".format(workspace_file))

    if init_vscode or os.path.exists(workspace_file):
        configure_vscode(setupdir, layerdir, bitbake_builddir, init_script)

def get_registry_config(registry_path, id):
    for root, _, files in os.walk(registry_path):
        for file in files:
            if file.endswith('.conf.json') and id == get_config_name(file):
                return os.path.join(root, file)
    raise Exception("Unable to find {} in available configurations; use 'list' sub-command to see what is available".format(id))

def merge_overrides_into_sources(sources, overrides):
    layers = copy.deepcopy(sources)
    for k,v in overrides.items():
        if k in layers:
            layers[k] = v
    return layers

def update_build(config, confdir, setupdir, layerdir, d, update_bb_conf="prompt", init_vscode=False, rebase_conflicts_strategy='abort'):
    layer_config = merge_overrides_into_sources(config["data"]["sources"], config["source-overrides"]["sources"])
    sources_fixed_revisions = checkout_layers(layer_config, confdir, layerdir, d, rebase_conflicts_strategy=rebase_conflicts_strategy)
    bitbake_config = config["bitbake-config"]
    thisdir = os.path.dirname(config["path"]) if config["type"] == 'local' else None
    setup_bitbake_build(bitbake_config, layerdir, setupdir, thisdir, update_bb_conf, init_vscode)
    write_sources_fixed_revisions(confdir, layerdir, sources_fixed_revisions)
    commit_config(confdir)

def int_input(allowed_values, prompt=''):
    n = None
    while n is None:
        try:
            n = int(input(prompt))
        except ValueError:
            prompt = 'Not a valid number, please try again: '
            continue
        if n not in allowed_values:
            prompt = 'Number {} not one of {}, please try again: '.format(n, allowed_values)
            n = None
    return n

def flatten_bitbake_configs(configs):
    def merge_configs(c1,c2):
        c_merged = {}
        for k,v in c2.items():
            if k not in c1.keys():
                c_merged[k] = v
        for k,v in c1.items():
            if k not in c2.keys():
                c_merged[k] = v
            else:
               c_merged[k] = c1[k] + c2[k]
        del c_merged['configurations']
        return c_merged

    flattened_configs = []
    for c in configs:
        if 'configurations' not in c:
            flattened_configs.append(c)
        else:
            for sub_c in flatten_bitbake_configs(c['configurations']):
                flattened_configs.append(merge_configs(c, sub_c))
    return flattened_configs

def choose_bitbake_config(configs, parameters, non_interactive):
    flattened_configs = flatten_bitbake_configs(configs)
    configs_dict = {i["name"]:i for i in flattened_configs}

    if parameters:
        config_id = parameters[0]
        if config_id not in configs_dict:
            raise Exception("Bitbake configuration {} not found; replace with one of {}".format(config_id, configs_dict))
        return configs_dict[config_id]

    enumerated_configs = list(enumerate(flattened_configs, 1))
    if len(enumerated_configs) == 1:
        only_config = flattened_configs[0]
        logger.plain("\nSelecting the only available bitbake configuration {}".format(only_config["name"]))
        return only_config

    if non_interactive:
        raise Exception("Unable to choose from bitbake configurations in non-interactive mode: {}".format(configs_dict))

    logger.plain("")
    print_configs("Available bitbake configurations",
                  [c["name"] for c in flattened_configs],
                  [c["description"] for c in flattened_configs])
    config_n = int_input([i[0] for i in enumerated_configs],
                         "\nPlease select one of the above bitbake configurations by its number: ") - 1
    return flattened_configs[config_n]

def choose_config(configs, non_interactive):
    not_expired_configs = [k for k in sorted(configs.keys()) if not has_expired(configs[k].get("expires", None))]
    if len(not_expired_configs) == 1:
        only_config = not_expired_configs[0]
        logger.plain("\nSelecting the only available configuration {}\n".format(only_config))
        return only_config

    if non_interactive:
        raise Exception("Unable to choose from configurations in non-interactive mode: {}".format(not_expired_configs))

    descs = []
    for c in not_expired_configs:
        d = configs[c]["description"]
        expiry_date = configs[c].get("expires", None)
        if expiry_date:
            d += f" (supported until {expiry_date})"
        descs.append(d)

    logger.plain("")
    print_configs("Available Configuration Templates",
                  [c for c in not_expired_configs],
                  descs)
    config_n = int_input([i[0] for i in list(enumerate(not_expired_configs, 1))],
                         "\nPlease select one of the above configurations by its number: ") - 1
    return not_expired_configs[config_n]

def choose_fragments(possibilities, parameters, non_interactive, skip_selection):
    choices = {}
    for k,v in possibilities.items():
        if skip_selection and k in skip_selection:
            logger.info("Skipping a selection of {}, as requested on command line. The resulting bitbake configuration may require further manual adjustments.".format(k))
            continue

        # options can be a list of strings or a list of dicts
        options = v["options"]
        if len(options) > 0 and isinstance(v["options"][0], str):
            options = [{"name": o, "description": ""} for o in v["options"]]

        choice = [o["name"] for o in options if o["name"] in parameters]
        if len(choice) > 1:
            raise Exception("Options specified on command line do not allow a single selection "
                            f"from possibilities {[o['name'] for o in options]}, please "
                            f"remove one or more from {parameters}")
        if len(choice) == 1:
            choices[k] = choice[0]
            continue

        if non_interactive:
            raise Exception(f"Unable to choose from options in non-interactive mode: {[o['name'] for o in options]}")

        logger.plain("")
        print_configs(v["description"],
                     [o['name'] for o in options],
                     [o['description'] for o in options])
        options_enumerated = list(enumerate(options, 1))
        option_n = int_input([i[0] for i in options_enumerated],
                             "\nPlease select one of the above options by its number: ") - 1
        choices[k] = options_enumerated[option_n][1]["name"]
    return choices

def obtain_config(top_dir, registry, args, source_overrides, d):
    if args.config:
        config_id = args.config[0]
        config_parameters = args.config[1:]
        if os.path.exists(config_id):
            config_id = os.path.abspath(config_id)
            logger.info("Reading configuration from local file\n    {}".format(config_id))
            upstream_config = {'type':'local',
                               'path':config_id,
                               'name':get_config_name(config_id),
                               'data':json.load(open(config_id))
                               }
        elif config_id.startswith("http://") or config_id.startswith("https://"):
            logger.info("Reading configuration from network URI\n    {}".format(config_id))
            import urllib.request
            try:
                with urllib.request.urlopen(config_id) as f:
                    json_data = json.load(f)
                upstream_config = {'type':'network','uri':config_id,'name':get_config_name(config_id),'data':json_data}
            except json.JSONDecodeError as e:
                raise Exception ("Invalid JSON from {}. Are you pointing to an HTML page? {}".format(config_id, e)) from e
        else:
            logger.info("Looking up config {} in configuration registry".format(config_id))
            registry_path = update_registry(registry, cache_dir(top_dir), d)
            registry_configs = list_registry(registry_path, with_expired=True)
            if config_id not in registry_configs:
                raise Exception("Config {} not found in configuration registry, re-run 'init' without parameters to choose from available configurations.".format(config_id))
            upstream_config = {'type':'registry','registry':registry,'name':config_id,'data':json.load(open(get_registry_config(registry_path,config_id)))}
        expiry_date = upstream_config['data'].get("expires", None)
        if has_expired(expiry_date):
            logger.warning("This configuration is no longer supported after {}. Please consider changing to a supported configuration.".format(expiry_date))
    else:
        registry_path = update_registry(registry, cache_dir(top_dir), d)
        registry_configs = list_registry(registry_path, with_expired=True)
        config_id = choose_config(registry_configs, args.non_interactive)
        config_parameters = []
        upstream_config = {'type':'registry','registry':registry,'name':config_id,'data':json.load(open(get_registry_config(registry_path,config_id)))}

    upstream_config['bitbake-config'] = choose_bitbake_config(upstream_config['data']['bitbake-setup']['configurations'], config_parameters, args.non_interactive)
    upstream_config['bitbake-config']['oe-fragment-choices'] = choose_fragments(upstream_config['bitbake-config'].get('oe-fragments-one-of',{}), config_parameters[1:], args.non_interactive, args.skip_selection)
    upstream_config['non-interactive-cmdline-options'] = [config_id, upstream_config['bitbake-config']['name']] + sorted(upstream_config['bitbake-config']['oe-fragment-choices'].values())
    upstream_config['source-overrides'] = source_overrides
    upstream_config['skip-selection'] = args.skip_selection
    return upstream_config

def obtain_overrides(args):
    overrides = {'sources':{}}
    if args.source_overrides:
        overrides = json.load(open(args.source_overrides))
        overrides_dir = os.path.dirname(os.path.abspath(args.source_overrides))
        for s,v in overrides['sources'].items():
            local = v.get('local')
            if local:
                path = os.path.expanduser(local['path'])
                if not os.path.isabs(path):
                    overrides['sources'][s]['local']['path'] = os.path.join(overrides_dir, path)

    for local_name, local_path in args.use_local_source:
        overrides['sources'][local_name] = {'local':{'path':os.path.abspath(os.path.expanduser(local_path))}}

    return overrides

def configure_vscode(setupdir, layerdir, builddir, init_script):
    """
    Configure the VSCode environment by creating or updating a workspace file.

    Create or update a bitbake.code-workspace file with folders for the layers and build/conf.
    Managed folders are regenerated; user-added folders are kept. Settings are merged, with
    managed keys (bitbake.*, python extra paths) always overwritten.
    """
    logger.debug("configure_vscode: setupdir={}, layerdir={}, builddir={}, init_script={}".format(
        setupdir, layerdir, builddir, init_script))

    # Get git repository directories
    git_repos = []
    if os.path.exists(layerdir):
        for entry in os.listdir(layerdir):
            entry_path = os.path.join(layerdir, entry)
            if os.path.isdir(entry_path) and not os.path.islink(entry_path):
                # Check if it's a git repository
                if os.path.exists(os.path.join(entry_path, '.git')):
                    git_repos.append(entry)
    logger.debug("configure_vscode: found {} git repos: {}".format(len(git_repos), git_repos))

    conf_path = os.path.relpath(os.path.join(builddir, "conf"), setupdir)
    repo_paths = [os.path.relpath(os.path.join(layerdir, repo), setupdir) for repo in git_repos]
    logger.debug("configure_vscode: conf_path={}, repo_paths={}".format(conf_path, repo_paths))

    # Load existing workspace
    workspace_file = os.path.join(setupdir, "bitbake.code-workspace")
    workspace = {
        "extensions": {
            "recommendations": [
                "yocto-project.yocto-bitbake"
            ]
        }
    }
    if os.path.exists(workspace_file):
        logger.debug("configure_vscode: loading existing workspace file: {}".format(workspace_file))
        try:
            with open(workspace_file, 'r') as f:
                workspace = json.load(f)
            logger.debug("configure_vscode: loaded workspace with {} folders, {} settings".format(
                len(workspace.get("folders", [])), len(workspace.get("settings", {}))))
        except (json.JSONDecodeError, OSError) as e:
            logger.error(
                "Unable to read existing workspace file {}: {}. Skipping update.".format(
                    workspace_file, str(e)
                )
            )
            return
    else:
        logger.debug("configure_vscode: creating new workspace file: {}".format(workspace_file))

    # Update folders
    existing_folders = workspace.get("folders", [])
    new_folders = [{"name": "conf", "path": conf_path}]
    for rp in repo_paths:
        repo_name = os.path.basename(rp)
        new_folders.append({"name": repo_name, "path": rp})
    # Keep any user-added folders that are not managed
    managed_paths = {f["path"] for f in new_folders}
    for f in existing_folders:
        if f["path"] not in managed_paths:
            new_folders.append(f)
            logger.debug("configure_vscode: keeping user-added folder: {}".format(f["path"]))
    workspace["folders"] = new_folders
    logger.debug("configure_vscode: updated workspace with {} folders".format(len(new_folders)))

    # Build Python extra paths for each layer - only check top level of each repo
    extra_paths = []
    subdirs_to_check = ['lib', 'scripts']
    for repo in git_repos:
        repo_path_abs = os.path.join(layerdir, repo)
        for subdir in subdirs_to_check:
            sub_path = os.path.join(repo_path_abs, subdir)
            if os.path.isdir(sub_path):
                extra_paths.append(sub_path)

    # Update settings
    existing_settings = workspace.get("settings", {})
    new_settings = {
        "bitbake.disableConfigModification": True,
        "bitbake.pathToBitbakeFolder": os.path.join(layerdir, "bitbake"),
        "bitbake.pathToBuildFolder": builddir,
        "bitbake.pathToEnvScript": init_script,
        "bitbake.workingDirectory": builddir,
        "files.associations": {
            "*.conf": "bitbake",
            "*.inc": "bitbake"
        },
        "files.exclude": {
            "**/.git/**": True
        },
        "search.exclude": {
            "**/.git/**": True,
            "**/logs/**": True
        },
        "files.watcherExclude": {
            "**/.git/**": True,
            "**/logs/**": True
        },
        "python.analysis.exclude": [
            "**/.git/**",
            "**/logs/**"
        ],
        "python.autoComplete.extraPaths": extra_paths,
        "python.analysis.extraPaths": extra_paths
    }

    # Merge settings: add missing, always update bitbake paths and python extra paths
    for key, value in new_settings.items():
        if key not in existing_settings:
            existing_settings[key] = value
        elif key.startswith("bitbake.") or key in [
            "python.autoComplete.extraPaths",
            "python.analysis.extraPaths",
        ]:
            # Always replace - these are managed/machine-generated settings
            existing_settings[key] = value
        elif key in [
            "files.associations",
            "files.exclude",
            "search.exclude",
            "files.watcherExclude",
            "python.analysis.exclude",
        ]:
            # For dicts and lists, merge new values in without removing user additions
            if isinstance(value, dict):
                if not isinstance(existing_settings[key], dict):
                    existing_settings[key] = {}
                for k, v in value.items():
                    if k not in existing_settings[key]:
                        existing_settings[key][k] = v
            elif isinstance(value, list):
                if not isinstance(existing_settings[key], list):
                    existing_settings[key] = []
                for item in value:
                    if item not in existing_settings[key]:
                        existing_settings[key].append(item)

    workspace["settings"] = existing_settings
    logger.debug("configure_vscode: merged settings, total {} keys".format(len(existing_settings)))

    with open(workspace_file, 'w') as f:
        json.dump(workspace, f, indent=4)
    logger.debug("configure_vscode: wrote workspace file: {}".format(workspace_file))

def init_config(top_dir, settings, args):
    create_siteconf(top_dir, args.non_interactive, settings)

    d = init_bb_cache(top_dir, settings, args)

    def handle_task_progress(event, d):
        rate = event.rate if event.rate else ''
        progress = event.progress if event.progress > 0 else 0
        logger.handlers[0].terminator = '\r'
        logger.plain("{}% {}                ".format(progress, rate))
        logger.handlers[0].terminator = '\n'

    source_overrides = obtain_overrides(args)
    upstream_config = obtain_config(top_dir, settings["default"]["registry"], args, source_overrides, d)
    logger.info("Run 'bitbake-setup init --non-interactive {}' to select this configuration non-interactively.\n".format(" ".join(upstream_config['non-interactive-cmdline-options'])))

    if args.setup_dir_name:
        setup_dir_name = args.setup_dir_name
    else:
        setup_dir_name = "{}-{}".format(upstream_config['name']," ".join(upstream_config['non-interactive-cmdline-options'][1:]).replace(" ","-").replace("/","_"))
        if 'setup-dir-name' in upstream_config['bitbake-config']:
            mapping = {
                    k: v.partition("/")[2].replace(" ", "-").replace("/", "_")
                    for k, v in upstream_config['bitbake-config']['oe-fragment-choices'].items()
            }
            config_setup_dir_name = string.Template(upstream_config['bitbake-config']['setup-dir-name']).substitute(mapping)
            config_setup_dir = os.path.join(top_dir, config_setup_dir_name)
            if os.path.exists(config_setup_dir):
                logger.info("Setup directory {} (as suggested by configuration) already exists, using the full name instead.\n".format(config_setup_dir))
            elif settings['default']['use-full-setup-dir-name'] != 'no':
                logger.info("Using the full setup directory name instead of {} suggested by configuration, as set in the settings.\n".format(config_setup_dir))
            else:
                setup_dir_name = config_setup_dir_name

        if not args.non_interactive:
            n = input(f"Enter setup directory name [{setup_dir_name}]: ")
            if n:
                setup_dir_name = n

    setupdir = os.path.join(os.path.abspath(top_dir), setup_dir_name)
    if os.path.exists(os.path.join(setupdir, "layers")):
        logger.info(f"Setup already initialized in:\n    {setupdir}\nUse 'bitbake-setup status' to check if it needs to be updated, or 'bitbake-setup update' to perform the update.\nIf you would like to start over and re-initialize in this directory, remove it, and run 'bitbake-setup init' again.")
        return

    logger.plain("Initializing a setup directory in\n    {}".format(setupdir))
    if not args.non_interactive:
        y_or_n = input('Continue? (y/N): ')
        if y_or_n != 'y':
            exit()
        logger.plain("")

    os.makedirs(setupdir, exist_ok=True)

    confdir = os.path.join(setupdir, "config")
    layerdir = os.path.join(setupdir, "layers")

    os.makedirs(confdir)
    os.makedirs(layerdir)

    bb.process.run(["git", "-C", confdir, "init", "-b", "main"])
    # Make sure commiting doesn't fail if no default git user is configured on the machine
    bb.process.run(["git", "-C", confdir, "config", "user.name", "bitbake-setup"])
    bb.process.run(["git", "-C", confdir, "config", "user.email", "bitbake-setup@not.set"])
    bb.process.run(["git", "-C", confdir, "commit", "--no-verify", "--allow-empty", "-m", "Initial commit"])

    bb.event.register("bb.build.TaskProgress", handle_task_progress, data=d)

    write_upstream_config(confdir, upstream_config)
    update_build(upstream_config, confdir, setupdir, layerdir, d, update_bb_conf="yes", init_vscode=args.init_vscode)

    bb.event.remove("bb.build.TaskProgress", None)

def get_diff(file1, file2):
    try:
        bb.process.run(["diff", get_diff_color_param(), "-uNr", file1, file2])
    except bb.process.ExecutionError as e:
        if e.exitcode == 1:
            return e.stdout
        else:
            raise e
    return None

def are_layers_changed(layers, layerdir, d):
    def _is_git_remote_changed(r_remote, repodir):
        from bb.fetch2.git import git_hash_re

        rev = r_remote['rev']
        branch = r_remote.get('branch', None)

        rev_parse_result = bb.process.run(['git', '-C', os.path.join(layerdir, repodir), "rev-parse", "HEAD"])
        local_revision = rev_parse_result[0].strip()
        if git_hash_re.match(rev):
            if rev != local_revision:
                logger.info('Layer repository checked out into {} is at revision {} but should be at {}'.format(os.path.join(layerdir, repodir),local_revision, rev))
                return True
            return False

        remotes = _get_remotes(r_remote)
        changed = False
        for remote in remotes:
            type,host,path,user,pswd,params = bb.fetch.decodeurl(remote)
            fetchuri = bb.fetch.encodeurl(('git',host,path,user,pswd,params))
            if branch:
                fetcher = bb.fetch.FetchData("{};protocol={};rev={};branch={};destsuffix={}".format(fetchuri,type,rev,branch,repodir), d)
            else:
                fetcher = bb.fetch.FetchData("{};protocol={};rev={};nobranch=1;destsuffix={}".format(fetchuri,type,rev,repodir), d)
            upstream_revision = fetcher.method.latest_revision(fetcher, d, 'default')
            if upstream_revision != local_revision:
                changed = True
                logger.info('Layer repository {} checked out into {} updated revision {} from {} to {}'.format(remote, os.path.join(layerdir, repodir), rev, local_revision, upstream_revision))
        return changed

    changed = False
    for r_name in layers:
        r_data = layers[r_name]
        repodir = r_data.get("path", r_name)

        git_remote = r_data.get('git-remote')
        if git_remote:
            changed = changed | _is_git_remote_changed(git_remote, repodir)

    return changed

def build_status(top_dir, settings, args, d, update=False):
    setupdir = os.path.abspath(args.setup_dir)

    confdir = os.path.join(setupdir, "config")
    layerdir = os.path.join(setupdir, "layers")

    current_upstream_config = json.load(open(os.path.join(confdir, "config-upstream.json")))

    args.config = current_upstream_config['non-interactive-cmdline-options']
    args.non_interactive = True
    args.skip_selection = current_upstream_config['skip-selection']
    source_overrides = current_upstream_config["source-overrides"]
    registry = current_upstream_config.get("registry")
    new_upstream_config = obtain_config(top_dir, registry, args, source_overrides, d)

    write_upstream_config(confdir, new_upstream_config)
    config_diff = bb.process.run(["git", "-C" , confdir, "diff", get_diff_color_param()])[0]

    if config_diff:
        logger.plain('\nConfiguration in {} has changed:\n{}'.format(setupdir, config_diff))
        if update:
            update_build(new_upstream_config, confdir, setupdir, layerdir, d,
                         update_bb_conf=args.update_bb_conf, rebase_conflicts_strategy=args.rebase_conflicts_strategy)
        else:
            bb.process.run(["git", "-C", confdir, "restore", "config-upstream.json"])
        return

    layer_config = merge_overrides_into_sources(current_upstream_config["data"]["sources"], current_upstream_config["source-overrides"]["sources"])
    if are_layers_changed(layer_config, layerdir, d):
        if update:
            update_build(current_upstream_config, confdir, setupdir, layerdir,
                         d, update_bb_conf=args.update_bb_conf, rebase_conflicts_strategy=args.rebase_conflicts_strategy)
        return

    logger.plain("\nConfiguration in {} has not changed.".format(setupdir))

def build_update(top_dir, settings, args, d):
    build_status(top_dir, settings, args, d, update=True)

def do_fetch(fetcher, dir):
    # git fetcher simply dumps git output to stdout; in bitbake context that is redirected to temp/log.do_fetch
    # and we need to set up smth similar here
    fetchlogdir = os.path.join(dir, 'logs')
    os.makedirs(fetchlogdir, exist_ok=True)
    fetchlog = os.path.join(fetchlogdir, 'fetch_log.{}'.format(datetime.datetime.now().strftime("%Y%m%d%H%M%S")))
    with open(fetchlog, 'a') as f:
        oldstdout = sys.stdout
        sys.stdout = f
        try:
            fetcher.download()
            fetcher.unpack_update(dir)
        finally:
            sys.stdout = oldstdout

def update_registry(registry, cachedir, d):
    registrydir = 'configurations'
    if registry.startswith("."):
        full_registrydir = os.path.join(os.getcwd(), registry, registrydir)
    elif registry.startswith("/"):
        full_registrydir = os.path.join(registry, registrydir)
    else:
        full_registrydir = os.path.join(cachedir, registrydir)
        logger.info("Fetching configuration registry\n    {}\ninto\n    {}".format(registry, full_registrydir))
        fetcher = bb.fetch.Fetch(["{};destsuffix={}".format(registry, registrydir)], d)
        do_fetch(fetcher, cachedir)
    return full_registrydir

def has_expired(expiry_date):
    if expiry_date:
        return datetime.datetime.now() > datetime.datetime.fromisoformat(expiry_date)
    return False

def list_registry(registry_path, with_expired):
    json_data = {}

    for root, _, files in os.walk(registry_path):
        for file in files:
            if file.endswith('.conf.json'):
                config_name = get_config_name(file)
                config_data = json.load(open(os.path.join(root, file)))
                config_desc = config_data["description"]
                expiry_date = config_data.get("expires", None)
                if expiry_date:
                    if with_expired or not has_expired(expiry_date):
                        json_data[config_name] = {"description": config_desc, "expires": expiry_date}
                else:
                    json_data[config_name] = {"description": config_desc}
    return json_data

def list_configs(settings, args):
    import tempfile
    top_dir = tempfile.mkdtemp(prefix="bitbake-setup-list-")
    settings['default']['dl-dir'] = os.path.join(top_dir, '.bitbake-setup-downloads')
    d = init_bb_cache(top_dir, settings, args)
    registry_path = update_registry(settings["default"]["registry"], cache_dir(top_dir), d)
    json_data = list_registry(registry_path, args.with_expired)
    shutil.rmtree(top_dir)

    logger.plain("Available configurations:")
    for config_name, config_data in sorted(json_data.items()):
        expiry_date = config_data.get("expires", None)
        config_desc = config_data["description"]
        if expiry_date:
           if args.with_expired or not has_expired(expiry_date):
               logger.plain("{}\t{} (supported until {})".format(config_name, config_desc, expiry_date))
        else:
           logger.plain("{}\t{}".format(config_name, config_desc))
    logger.plain("\nRun 'init' with one of the above configuration identifiers to set up a build.")

    if args.write_json:
        with open(args.write_json, 'w') as f:
            json.dump(json_data, f, sort_keys=True, indent=4)
        logger.plain("Available configurations written into {}".format(args.write_json))

def install_buildtools(top_dir, settings, args, d):
    buildtools_install_dir = os.path.join(args.setup_dir, 'buildtools')
    if os.path.exists(buildtools_install_dir):
        if not args.force:
            logger.plain("Buildtools are already installed in {}.".format(buildtools_install_dir))
            env_scripts = glob.glob(os.path.join(buildtools_install_dir, 'environment-setup-*'))
            if env_scripts:
                logger.plain("If you wish to use them, you need to source the environment setup script e.g.")
                for s in env_scripts:
                    logger.plain("$ . {}".format(s))
            logger.plain("You can also re-run bitbake-setup install-buildtools with --force option to force a reinstallation.")
            return
        shutil.rmtree(buildtools_install_dir)

    install_buildtools_script = os.path.join(args.setup_dir, 'layers/oe-scripts/install-buildtools')

    buildtools_config = {}
    upstream_config_path = os.path.join(args.setup_dir, 'config', 'config-upstream.json')
    try:
        with open(upstream_config_path) as f:
            upstream_config = json.load(f)
        buildtools_config = upstream_config.get('bitbake-config', {}).get('install-buildtools', {})
    except FileNotFoundError:
        pass
    except json.JSONDecodeError as e:
        logger.error("Failed to parse %s: %s" % (upstream_config_path, e))
        sys.exit(1)

    url = args.url if args.url is not None else buildtools_config.get('url')
    sha256 = args.sha256 if args.sha256 is not None else buildtools_config.get('sha256sum')

    buildtools_download_dir = add_unique_timestamp_to_path(
        os.path.join(args.setup_dir, 'buildtools-downloads/buildtools'))

    if args.default or (not url and not sha256):
        # No config or --default: fall back to install-buildtools defaults
        logger.plain("Using install-buildtools script defaults")
        subprocess.check_call([install_buildtools_script,
                               '-d', buildtools_install_dir,
                               '--downloads-directory', buildtools_download_dir])
        return

    if not url:
        logger.error("No buildtools URL configured. "
                     "Set 'url' in the install-buildtools config section or pass --url.")
        sys.exit(1)

    if not sha256:
        logger.error("No sha256sum configured for buildtools installer. "
                     "Add 'sha256sum' to the install-buildtools config section or pass --sha256.\n"
                     "You can obtain it with: sha256sum <installer-file>")
        sys.exit(1)

    # Download using bb.fetch with sha256 validation
    src_uri = "{};sha256sum={}".format(url, sha256)

    logger.plain("Fetching buildtools installer using bitbake fetcher")
    logger.plain("    {}".format(url))

    fetcher = bb.fetch.Fetch([src_uri], d)
    try:
        fetcher.download()
    except bb.fetch2.ChecksumError as e:
        logger.error("Checksum mismatch for buildtools installer. "
                     "Verify the URL and downloaded file.\n%s" % str(e))
        sys.exit(1)
    except bb.fetch2.FetchError as e:
        logger.error("Failed to download buildtools installer: %s" % str(e))
        sys.exit(1)

    # Unpack into the standard buildtools download location
    os.makedirs(buildtools_download_dir, exist_ok=True)
    fetcher.unpack(buildtools_download_dir)

    filename = os.path.basename(url.rstrip('/'))
    matches = glob.glob(os.path.join(buildtools_download_dir, '**', filename), recursive=True)
    if not matches:
        logger.error("Unpacked file not found: %s" % filename)
        sys.exit(1)
    local_path = matches[0]

    logger.plain("Buildtools installer will be installed into {}".format(
        buildtools_install_dir))

    cmd = [
        install_buildtools_script,
        '--local-file', local_path,
        '-d', buildtools_install_dir,
    ]

    try:
        subprocess.check_call(cmd)
    except subprocess.CalledProcessError as e:
        logger.error("install-buildtools failed with exit code %d" % e.returncode)
        sys.exit(1)

def create_siteconf(top_dir, non_interactive, settings):
    siteconfpath = os.path.join(top_dir, 'site.conf')
    if os.path.exists(siteconfpath):
        logger.info('A site.conf file already exists. Please remove it if you would like to replace it with a default one')
    else:
        logger.plain(f'{top_dir} looks like a new top directory. If you would like to use a different directory, answer "n" below and either:')
        logger.plain('\t1) Change the default bitbake-setup settings:')
        logger.plain('\t\tbitbake-setup settings set default top-dir-prefix <PATH>')
        logger.plain('\t\tbitbake-setup settings set default top-dir-name <NAME>')
        logger.plain('\t2) Pass one or more options on the command line to change the top level directory in that invocation only:')
        logger.plain('\t\tbitbake-setup --setting default top-dir-prefix <PATH> ...')
        logger.plain('\t\tbitbake-setup --setting default top-dir-name <NAME> ...')
        logger.plain('')

        logger.plain('A common site.conf file will be created, please check it is correct before running builds\n    {}\n'.format(siteconfpath))
        if not non_interactive:
            y_or_n = input('Proceed? (y/N): ')
            if y_or_n != 'y':
                exit()

        os.makedirs(top_dir, exist_ok=True)
        with open(siteconfpath, 'w') as siteconffile:
            sstate_settings = textwrap.dedent(
                """
                #
                # Where to place shared-state files
                #
                # BitBake has the capability to accelerate builds based on previously built output.
                # This is done using "shared state" files which can be thought of as cache objects
                # and this option determines where those files are placed.
                #
                # You can wipe out TMPDIR leaving this directory intact and the build would regenerate
                # from these files if no changes were made to the configuration. If changes were made
                # to the configuration, only shared state files where the state was still valid would
                # be used (done using checksums).
                SSTATE_DIR ?= "{sstate_dir}"
                #
                # Hash Equivalence database location
                #
                # Hash equivalence improves reuse of sstate by detecting when a given sstate
                # artifact can be reused as equivalent, even if the current task hash doesn't
                # match the one that generated the artifact. This variable controls where the
                # Hash Equivalence database ("hashserv.db") is stored and can be shared between
                # concurrent builds.
                BB_HASHSERVE_DB_DIR ?= "${{SSTATE_DIR}}"
                """.format(sstate_dir=os.path.join(top_dir, ".sstate-cache"))
            )
            siteconffile.write(
                textwrap.dedent(
                    """\
                    # This file is intended for build host-specific bitbake settings

                    # Where to place downloads
                    #
                    # During a first build the system will download many different source code
                    # tarballs from various upstream projects. This can take a while, particularly
                    # if your network connection is slow. These are all stored in DL_DIR. When
                    # wiping and rebuilding you can preserve this directory to speed up this part of
                    # subsequent builds. This directory is safe to share between multiple builds on
                    # the same machine too.
                    DL_DIR ?= "{dl_dir}"
                    """.format(
                        dl_dir=settings["default"]["dl-dir"],
                    )
                ) + (sstate_settings if settings["default"]["common-sstate"] == 'yes' else "")
            )


def topdir_settings_path(top_dir):
    return os.path.join(top_dir, 'settings.conf')

def global_settings_path(args):
    return os.path.abspath(args.global_settings) if args.global_settings else os.path.join(os.path.expanduser('~'), '.config', 'bitbake-setup', 'settings.conf')

def load_settings(settings_path):
    settings = configparser.ConfigParser()
    if os.path.exists(settings_path):
        logger.info('Loading settings from {}'.format(settings_path))
        settings.read_file(open(settings_path))

        for section in settings.sections():
            for key, value in settings[section].items():
                settings[section][key] = value.strip('\"\'')

    return settings

def change_setting(top_dir, args):
    if vars(args)['global']:
        settings_path = global_settings_path(args)
    elif args.setting in GLOBAL_ONLY_SETTINGS:
        logger.info(f"{args.setting} can only be set in the global config; '--global' is implied")
        settings_path = global_settings_path(args)
    else:
        settings_path = topdir_settings_path(top_dir)
    settings = load_settings(settings_path)

    if args.subcommand == 'set':
        if args.section not in settings.keys():
            settings[args.section] = {}
        settings[args.section][args.setting] = args.value
        logger.plain(f"From section '{args.section}' the setting '{args.setting}' was changed to '{args.value}'")
    if args.subcommand == 'unset':
        if args.section in settings.keys() and args.setting in settings[args.section].keys():
            del settings[args.section][args.setting]
            logger.plain(f"From section '{args.section}' the setting '{args.setting}' has been removed")

    os.makedirs(os.path.dirname(settings_path), exist_ok=True)
    with open(settings_path, 'w') as settingsfile:
        settings.write(settingsfile)
    logger.info(f"Settings written to {settings_path}")

def list_settings(all_settings):
    for section, section_settings in all_settings.items():
        for key, value in section_settings.items():
            logger.plain("{} {} {}".format(section, key, value))

def settings_func(top_dir, all_settings, args):
    if args.subcommand == 'list':
        list_settings(all_settings)
    elif args.subcommand == 'set' or args.subcommand == 'unset':
        change_setting(top_dir, args)

def get_setup_dir_via_bbpath():
    bbpath = os.environ.get('BBPATH')
    if bbpath:
        bitbake_dir = os.path.normpath(bbpath.split(':')[0])
        if os.path.exists(os.path.join(bitbake_dir,'init-build-env')):
            setup_dir = os.path.dirname(bitbake_dir)
            return setup_dir
    return None

def get_top_dir(args, settings):
    setup_dir_via_bbpath = get_setup_dir_via_bbpath()
    if setup_dir_via_bbpath:
        top_dir = os.path.dirname(setup_dir_via_bbpath)
        if os.path.exists(cache_dir(top_dir)):
            return top_dir

    if hasattr(args, 'setup_dir'):
        top_dir = os.path.dirname(os.path.normpath(args.setup_dir))
        return top_dir

    top_dir_prefix = settings['default']['top-dir-prefix']
    top_dir_name = settings['default']['top-dir-name']
    return os.path.join(top_dir_prefix, top_dir_name)

def merge_settings(builtin_settings, global_settings, topdir_settings, cmdline_settings):
    all_settings = builtin_settings

    for s in (global_settings, topdir_settings):
        for section, section_settings in s.items():
            for setting, value in section_settings.items():
                if section not in all_settings.keys():
                    all_settings[section] = {}
                all_settings[section][setting] = value

    for (section, setting, value) in cmdline_settings:
        if section not in all_settings.keys():
            all_settings[section] = {}
        all_settings[section][setting] = value

    return all_settings

def sigint_handler(sig, frame, func, top_dir):
    logger.plain('\nShutting down...')
    if isinstance(top_dir, str) and os.path.exists(top_dir):
        if func in [init_config, build_update]:
            logger.warning(f'{top_dir} may contain an incomplete setup!')
        elif func == install_buildtools:
            logger.warning(f'{top_dir} may contain an incomplete buildtools installation!')
    exit()

def main():
    def add_setup_dir_arg(parser):
        setup_dir = get_setup_dir_via_bbpath()
        if setup_dir:
            parser.add_argument('--setup-dir', default=setup_dir, help="Path to the setup, default is %(default)s via BBPATH")
        else:
            parser.add_argument('--setup-dir', required=True, help="Path to the setup")

    parser = argparse.ArgumentParser(
        description="BitBake setup utility. Run with 'init' argument to get started.",
        epilog="Use %(prog)s <subcommand> --help to get help on a specific command"
        )
    parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
    parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true')
    parser.add_argument('--version', action='version', version='%(prog)s ' + __version__)
    parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR')
    parser.add_argument('--no-network', action='store_true', help='Do not check whether configuration repositories and layer repositories have been updated; use only the local cache.')
    parser.add_argument('--global-settings', action='store', metavar='PATH', help='Path to the global settings file.')
    parser.add_argument('--setting', default=[], action='append', dest='cmdline_settings',
                        nargs=3, metavar=('SECTION', 'SETTING', 'VALUE'),
                        help='Modify a setting (for this bitbake-setup invocation only), for example "--setting default top-dir-prefix /path/to/top/dir".')

    subparsers = parser.add_subparsers()

    parser_list = subparsers.add_parser('list', help='List available configurations')
    parser_list.add_argument('--with-expired', action='store_true', help='List also configurations that are no longer supported due to reaching their end-of-life dates.')
    parser_list.add_argument('--write-json', action='store', help='Write available configurations into a json file so they can be programmatically processed.')
    parser_list.set_defaults(func=list_configs)

    parser_init = subparsers.add_parser('init', help='Select a configuration and initialize a setup from it')
    parser_init.add_argument('config', nargs='*', help="path/URL/id to a configuration file (use 'list' command to get available ids), followed by configuration options. Bitbake-setup will ask to choose from available choices if command line doesn't completely specify them.")
    parser_init.add_argument('--non-interactive', action='store_true', help='Do not ask to interactively choose from available options; if bitbake-setup cannot make a decision it will stop with a failure.')
    parser_init.add_argument('--source-overrides', action='store', help='Override sources information (repositories/revisions) with values from a local json file.')
    parser_init.add_argument('--setup-dir-name', action='store', help='A custom setup directory name under the top directory.')
    parser_init.add_argument('--skip-selection', action='append', help='Do not select and set an option/fragment from available choices; the resulting bitbake configuration may be incomplete.')
    parser_init.add_argument('-L', '--use-local-source', default=[], action='append', nargs=2, metavar=('SOURCE_NAME', 'PATH'),
                        help='Symlink local source into a build, instead of getting it as prescribed by a configuration (useful for local development).')
    parser_init.add_argument('--init-vscode', action=argparse.BooleanOptionalAction, default=bool(shutil.which('code')),
                        help='Generate VSCode workspace configuration (default: %(default)s)')
    parser_init.set_defaults(func=init_config)

    parser_status = subparsers.add_parser('status', help='Check if the setup needs to be synchronized with configuration')
    add_setup_dir_arg(parser_status)
    parser_status.set_defaults(func=build_status)

    parser_update = subparsers.add_parser('update', help='Update a setup to be in sync with configuration')
    add_setup_dir_arg(parser_update)
    parser_update.add_argument('--update-bb-conf', choices=['prompt', 'yes', 'no'], default='prompt', help='Update bitbake configuration files (bblayers.conf, local.conf) (default: prompt)')
    parser_update.add_argument('--rebase-conflicts-strategy', choices=['abort', 'backup'], default='abort',
                        help="What to do when a layer repository has local modifications that prevent "
                             "an in-place update: 'abort' (default) aborts with an error message; "
                             "'backup' renames the directory to a timestamped backup and re-clones from upstream.")
    parser_update.set_defaults(func=build_update)

    parser_install_buildtools = subparsers.add_parser('install-buildtools', help='Install buildtools which can help fulfil missing or incorrect dependencies on the host machine')
    add_setup_dir_arg(parser_install_buildtools)
    parser_install_buildtools.add_argument('--force', action='store_true', help='Force a reinstall of buildtools over the previous installation.')
    parser_install_buildtools.add_argument('--default', action='store_true', help='Use install-buildtools script defaults, ignoring any config.')
    parser_install_buildtools.add_argument('--url', help='Full URL to the buildtools SDK installer. Overrides config value.')
    parser_install_buildtools.add_argument('--sha256', help='SHA256 checksum of the buildtools installer. Overrides config value.')
    parser_install_buildtools.set_defaults(func=install_buildtools)

    parser_settings_arg_global = argparse.ArgumentParser(add_help=False)
    parser_settings_arg_global.add_argument('--global', action='store_true', help="Modify the setting in a global settings file, rather than one specific to a top directory")

    parser_settings = subparsers.add_parser('settings',
                                            help='List current settings, or set or unset a setting in a settings file (e.g. the default prefix and name of the top directory, the location of configuration registry, downloads directory and other settings specific to a top directory)')
    parser_settings.set_defaults(func=settings_func)

    subparser_settings = parser_settings.add_subparsers(dest="subcommand", required=True, help="The action to perform on the settings file")

    subparser_settings.add_parser('list', help="List all settings with their values")

    parser_settings_set = subparser_settings.add_parser('set', parents=[parser_settings_arg_global],
                                                        help="In a Section, set a setting to a certain value")
    parser_settings_set.add_argument("section", metavar="<section>", help="Section in a settings file, typically 'default'")
    parser_settings_set.add_argument("setting", metavar="<setting>", help="Name of a setting")
    parser_settings_set.add_argument("value", metavar="<value>", help="The setting value")

    parser_settings_unset = subparser_settings.add_parser('unset', parents=[parser_settings_arg_global],
                                                          help="Unset a setting, e.g. 'bitbake-setup settings unset default registry' would revert to the registry setting in a global settings file")
    parser_settings_unset.add_argument("section", metavar="<section>", help="Section in a settings file, typically 'default'")
    parser_settings_unset.add_argument("setting", metavar="<setting>", help="The setting to remove")

    args = parser.parse_args()

    if args.debug:
        logger.setLevel(logging.DEBUG)
    elif args.quiet:
        logger.setLevel(logging.ERROR)

    # Need to re-run logger_create with color argument
    # (will be the same logger since it has the same name)
    bb.msg.logger_create('bitbake-setup', output=sys.stdout,
                         color=args.color,
                         level=logger.getEffectiveLevel())

    if 'func' in args:
        if hasattr(args, 'setup_dir'):
            if not os.path.exists(os.path.join(args.setup_dir,'build', 'init-build-env')):
                logger.error("Not a valid setup directory: build/init-build-env does not exist in {}".format(args.setup_dir))
                return

        if not hasattr(args, 'non_interactive'):
            args.non_interactive = True

        builtin_settings = {}
        builtin_settings['default'] = {
                         'top-dir-prefix':os.getcwd(),
                         'top-dir-name':'bitbake-builds',
                         'registry':get_default_registry(),
                         'use-full-setup-dir-name':'no',
                         'common-sstate':'yes',
                         }

        global_settings = load_settings(global_settings_path(args))
        top_dir = get_top_dir(args, merge_settings(builtin_settings, global_settings, {}, args.cmdline_settings))

        # register handler now to pass top_dir
        _handler = functools.partial(sigint_handler,
                                     func=args.func,
                                     top_dir=os.path.abspath(top_dir))
        signal.signal(signal.SIGINT, _handler)

        # This cannot be set with the rest of the builtin settings as top_dir needs to be determined first
        builtin_settings['default']['dl-dir'] = os.path.join(top_dir, '.bitbake-setup-downloads')

        topdir_settings = load_settings(topdir_settings_path(top_dir))
        all_settings = merge_settings(builtin_settings, global_settings, topdir_settings, args.cmdline_settings)

        if args.func == settings_func:
            settings_func(top_dir, all_settings, args)
            return
        if args.func == list_configs:
            list_configs(all_settings, args)
            return

        logger.info('Bitbake-setup is using {} as top directory.'.format(top_dir))

        try:
            if args.func == init_config:
                init_config(top_dir, all_settings, args)
            else:
                d = init_bb_cache(top_dir, all_settings, args)
                args.func(top_dir, all_settings, args, d)

            save_bb_cache()
        except (SystemExit, KeyboardInterrupt):
            raise
        except Exception as e:
            if args.debug:
                raise
            logger.error(str(e))
            sys.exit(1)
    else:
        parser.print_help()

if __name__ == '__main__':
    main()
