#!/usr/bin/env python3
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

import argparse
import json
import os
import subprocess

def defaultlayers():
    return os.path.abspath(os.path.join(os.path.dirname(__file__), '.oe-layers.json'))

def makebuildpath(topdir, template):
    return os.path.join(topdir, "build-{}".format(template))

def discover_templates(layers_file):
    if not os.path.exists(layers_file):
        print("List of layers {} does not exist; were the layers set up using the setup-layers script?".format(layers_file))
        return None

    templates = []
    layers_list = json.load(open(layers_file))["layers"]
    for layer in layers_list:
        template_dir = os.path.join(os.path.dirname(layers_file), layer, 'conf','templates')
        if os.path.exists(template_dir):
            for d in sorted(os.listdir(template_dir)):
                templatepath = os.path.join(template_dir,d)
                if not os.path.isfile(os.path.join(templatepath,'local.conf.sample')):
                    continue
                layer_base = os.path.basename(layer)
                templatename = "{}-{}".format(layer_base[5:] if layer_base.startswith("meta-") else layer_base, d)
                buildpath = makebuildpath(os.getcwd(), templatename)
                notespath = os.path.join(template_dir, d, 'conf-notes.txt')
                try: notes = open(notespath).read()
                except: notes = None
                try: summary = open(os.path.join(template_dir, d, 'conf-summary.txt')).read()
                except: summary = None
                templates.append({"templatename":templatename,"templatepath":templatepath,"buildpath":buildpath,"notespath":notespath,"notes":notes,"summary":summary})

    return templates

def print_templates(templates, verbose):
    print("Available build configurations:\n")

    for i in range(len(templates)):
        t = templates[i]
        print("{}. {}".format(i+1, t["templatename"]))
        print("{}".format(t["summary"].strip() if t["summary"] else "This configuration does not have a summary."))
        if verbose:
            print("Configuration template path:", t["templatepath"])
            print("Build path:", t["buildpath"])
            print("Usage notes:", t["notespath"] if t["notes"] else "This configuration does not have usage notes.")
        print("")
    if not verbose:
        print("Re-run with 'list -v' to see additional information.")

def list_templates(args):
    templates = discover_templates(args.layerlist)
    if not templates:
        return

    verbose = args.v
    print_templates(templates, verbose)

def find_template(template_name, templates):
    print_templates(templates, False)
    if not template_name:
        n_s = input("Please choose a configuration by its number: ")
        try: return templates[int(n_s) - 1]
        except:
            print("Invalid selection, please try again.")
            return None
    else:
        for t in templates:
            if t["templatename"] == template_name:
                return t
        print("Configuration {} is not one of {}, please try again.".format(tempalte_name, [t["templatename"] for t in templates]))
        return None

def setup_build_env(args):
    templates = discover_templates(args.layerlist)
    if not templates:
        return

    template = find_template(args.c, templates)
    if not template:
        return
    builddir = args.b if args.b else template["buildpath"]
    no_shell = args.no_shell
    coredir = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
    cmd_base = ". {} {}".format(os.path.join(coredir, 'oe-init-build-env'), os.path.abspath(builddir))

    initbuild = os.path.join(builddir, 'init-build-env')
    if not os.path.exists(initbuild):
        os.makedirs(builddir, exist_ok=True)
        with open(initbuild, 'w') as f:
            f.write(cmd_base)
    print("\nRun '. {}' to initialize the build in a current shell session.\n".format(initbuild))

    cmd = "TEMPLATECONF={} {}".format(template["templatepath"], cmd_base)
    if not no_shell:
        cmd = cmd + " && {}".format(os.environ['SHELL'])
    print("Running:", cmd)
    subprocess.run(cmd, shell=True, executable=os.environ['SHELL'])

parser = argparse.ArgumentParser(description="A script that discovers available build configurations and sets up a build environment based on one of them. Run without arguments to choose one interactively.")
parser.add_argument("--layerlist", default=defaultlayers(), help='Where to look for available layers (as written out by setup-layers script) (default is {}).'.format(defaultlayers()))

subparsers = parser.add_subparsers()
parser_list_templates = subparsers.add_parser('list', help='List available configurations')
parser_list_templates.add_argument('-v', action='store_true',
        help='Print detailed information and usage notes for each available build configuration.')
parser_list_templates.set_defaults(func=list_templates)

parser_setup_env = subparsers.add_parser('setup', help='Set up a build environment and open a shell session with it, ready to run builds.')
parser_setup_env.add_argument('-c', metavar='configuration_name', help="Use a build configuration configuration_name to set up a build environment (run this script with 'list' to see what is available)")
parser_setup_env.add_argument('-b', metavar='build_path', help="Set up a build directory in build_path (run this script with 'list -v' to see where it would be by default)")
parser_setup_env.add_argument('--no-shell', action='store_true',
        help='Create a build directory but do not start a shell session with the build environment from it.')
parser_setup_env.set_defaults(func=setup_build_env)

args = parser.parse_args()

if 'func' in args:
    args.func(args)
else:
    from argparse import Namespace
    setup_build_env(Namespace(layerlist=args.layerlist, c=None, b=None, no_shell=False))
