#!/usr/bin/env python3
#
# Copyright (c) 2013, Intel Corporation.
#
# SPDX-License-Identifier: GPL-2.0-only
#
# DESCRIPTION 'wic' is the OpenEmbedded Image Creator that users can
# use to generate bootable images.  Invoking it without any arguments
# will display help screens for the 'wic' command and list the
# available 'wic' subcommands.  Invoking a subcommand without any
# arguments will likewise display help screens for the specified
# subcommand.  Please use that interface for detailed help.
#
# AUTHORS
# Tom Zanussi <tom.zanussi (at] linux.intel.com>
#
__version__ = "0.2.0"

# Python Standard Library modules
import os
import sys
import argparse
import logging
import subprocess

from collections import namedtuple
from distutils import spawn

# External modules
scripts_path = os.path.dirname(os.path.realpath(__file__))
lib_path = scripts_path + '/lib'
sys.path.insert(0, lib_path)
import scriptpath
scriptpath.add_oe_lib_path()

# Check whether wic is running within eSDK environment
sdkroot = scripts_path
if os.environ.get('SDKTARGETSYSROOT'):
    while sdkroot != '' and sdkroot != os.sep:
        if os.path.exists(os.path.join(sdkroot, '.devtoolbase')):
            # Set BUILDDIR for wic to work within eSDK
            os.environ['BUILDDIR'] = sdkroot
            # .devtoolbase only exists within eSDK
            # If found, initialize bitbake path for eSDK environment and append to PATH
            sdkroot = os.path.join(os.path.dirname(scripts_path), 'bitbake', 'bin')
            os.environ['PATH'] += ":" + sdkroot
            break
        sdkroot = os.path.dirname(sdkroot)

bitbake_exe = spawn.find_executable('bitbake')
if bitbake_exe:
    bitbake_path = scriptpath.add_bitbake_lib_path()
    import bb

from wic import WicError
from wic.misc import get_bitbake_var, BB_VARS
from wic import engine
from wic import help as hlp


def wic_logger():
    """Create and convfigure wic logger."""
    logger = logging.getLogger('wic')
    logger.setLevel(logging.INFO)

    handler = logging.StreamHandler()

    formatter = logging.Formatter('%(levelname)s: %(message)s')
    handler.setFormatter(formatter)

    logger.addHandler(handler)

    return logger

logger = wic_logger()

def rootfs_dir_to_args(krootfs_dir):
    """
    Get a rootfs_dir dict and serialize to string
    """
    rootfs_dir = ''
    for key, val in krootfs_dir.items():
        rootfs_dir += ' '
        rootfs_dir += '='.join([key, val])
    return rootfs_dir.strip()


class RootfsArgAction(argparse.Action):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def __call__(self, parser, namespace, value, option_string=None):
        if not "rootfs_dir" in vars(namespace) or \
           not type(namespace.__dict__['rootfs_dir']) is dict:
            namespace.__dict__['rootfs_dir'] = {}

        if '=' in value:
            (key, rootfs_dir) = value.split('=')
        else:
            key = 'ROOTFS_DIR'
            rootfs_dir = value

        namespace.__dict__['rootfs_dir'][key] = rootfs_dir


def wic_create_subcommand(options, usage_str):
    """
    Command-line handling for image creation.  The real work is done
    by image.engine.wic_create()
    """
    if options.build_rootfs and not bitbake_exe:
        raise WicError("Can't build rootfs as bitbake is not in the $PATH")

    if not options.image_name:
        missed = []
        for val, opt in [(options.rootfs_dir, 'rootfs-dir'),
                         (options.bootimg_dir, 'bootimg-dir'),
                         (options.kernel_dir, 'kernel-dir'),
                         (options.native_sysroot, 'native-sysroot')]:
            if not val:
                missed.append(opt)
        if missed:
            raise WicError("The following build artifacts are not specified: %s" %
                           ", ".join(missed))

    if options.image_name:
        BB_VARS.default_image = options.image_name
    else:
        options.build_check = False

    if options.vars_dir:
        BB_VARS.vars_dir = options.vars_dir

    if options.build_check and not engine.verify_build_env():
        raise WicError("Couldn't verify build environment, exiting")

    if options.debug:
        logger.setLevel(logging.DEBUG)

    if options.image_name:
        if options.build_rootfs:
            argv = ["bitbake", options.image_name]
            if options.debug:
                argv.append("--debug")

            logger.info("Building rootfs...\n")
            subprocess.check_call(argv)

        rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", options.image_name)
        kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE", options.image_name)
        bootimg_dir = get_bitbake_var("STAGING_DATADIR", options.image_name)

        native_sysroot = options.native_sysroot
        if options.vars_dir and not native_sysroot:
            native_sysroot = get_bitbake_var("RECIPE_SYSROOT_NATIVE", options.image_name)
    else:
        if options.build_rootfs:
            raise WicError("Image name is not specified, exiting. "
                           "(Use -e/--image-name to specify it)")
        native_sysroot = options.native_sysroot

    if not options.vars_dir and (not native_sysroot or not os.path.isdir(native_sysroot)):
        logger.info("Building wic-tools...\n")
        subprocess.check_call(["bitbake", "wic-tools"])
        native_sysroot = get_bitbake_var("RECIPE_SYSROOT_NATIVE", "wic-tools")

    if not native_sysroot:
        raise WicError("Unable to find the location of the native tools sysroot")

    wks_file = options.wks_file

    if not wks_file.endswith(".wks"):
        wks_file = engine.find_canned_image(scripts_path, wks_file)
        if not wks_file:
            raise WicError("No image named %s found, exiting.  (Use 'wic list images' "
                           "to list available images, or specify a fully-qualified OE "
                           "kickstart (.wks) filename)" % options.wks_file)

    if not options.image_name:
        rootfs_dir = ''
        if 'ROOTFS_DIR' in options.rootfs_dir:
            rootfs_dir = options.rootfs_dir['ROOTFS_DIR']
        bootimg_dir = options.bootimg_dir
        kernel_dir = options.kernel_dir
        native_sysroot = options.native_sysroot
        if rootfs_dir and not os.path.isdir(rootfs_dir):
            raise WicError("--rootfs-dir (-r) not found, exiting")
        if not os.path.isdir(bootimg_dir):
            raise WicError("--bootimg-dir (-b) not found, exiting")
        if not os.path.isdir(kernel_dir):
            raise WicError("--kernel-dir (-k) not found, exiting")
        if not os.path.isdir(native_sysroot):
            raise WicError("--native-sysroot (-n) not found, exiting")
    else:
        not_found = not_found_dir = ""
        if not os.path.isdir(rootfs_dir):
            (not_found, not_found_dir) = ("rootfs-dir", rootfs_dir)
        elif not os.path.isdir(kernel_dir):
            (not_found, not_found_dir) = ("kernel-dir", kernel_dir)
        elif not os.path.isdir(native_sysroot):
            (not_found, not_found_dir) = ("native-sysroot", native_sysroot)
        if not_found:
            if not not_found_dir:
                not_found_dir = "Completely missing artifact - wrong image (.wks) used?"
            logger.info("Build artifacts not found, exiting.")
            logger.info("  (Please check that the build artifacts for the machine")
            logger.info("   selected in local.conf actually exist and that they")
            logger.info("   are the correct artifacts for the image (.wks file)).\n")
            raise WicError("The artifact that couldn't be found was %s:\n  %s", not_found, not_found_dir)

    krootfs_dir = options.rootfs_dir
    if krootfs_dir is None:
        krootfs_dir = {}
        krootfs_dir['ROOTFS_DIR'] = rootfs_dir

    rootfs_dir = rootfs_dir_to_args(krootfs_dir)

    logger.info("Creating image(s)...\n")
    engine.wic_create(wks_file, rootfs_dir, bootimg_dir, kernel_dir,
                      native_sysroot, options)


def wic_list_subcommand(args, usage_str):
    """
    Command-line handling for listing available images.
    The real work is done by image.engine.wic_list()
    """
    if not engine.wic_list(args, scripts_path):
        raise WicError("Bad list arguments, exiting")


def wic_ls_subcommand(args, usage_str):
    """
    Command-line handling for list content of images.
    The real work is done by engine.wic_ls()
    """
    engine.wic_ls(args, args.native_sysroot)

def wic_cp_subcommand(args, usage_str):
    """
    Command-line handling for copying files/dirs to images.
    The real work is done by engine.wic_cp()
    """
    engine.wic_cp(args, args.native_sysroot)

def wic_rm_subcommand(args, usage_str):
    """
    Command-line handling for removing files/dirs from images.
    The real work is done by engine.wic_rm()
    """
    engine.wic_rm(args, args.native_sysroot)

def wic_write_subcommand(args, usage_str):
    """
    Command-line handling for writing images.
    The real work is done by engine.wic_write()
    """
    engine.wic_write(args, args.native_sysroot)

def wic_help_subcommand(args, usage_str):
    """
    Command-line handling for help subcommand to keep the current
    structure of the function definitions.
    """
    pass


def wic_help_topic_subcommand(usage_str, help_str):
    """
    Display function for help 'sub-subcommands'.
    """
    print(help_str)
    return


wic_help_topic_usage = """
"""

helptopics = {
    "plugins":   [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_plugins_help],
    "overview":  [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_overview_help],
    "kickstart": [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_kickstart_help],
    "create":    [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_create_help],
    "ls":        [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_ls_help],
    "cp":        [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_cp_help],
    "rm":        [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_rm_help],
    "write":     [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_write_help],
    "list":      [wic_help_topic_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_list_help]
}


def wic_init_parser_create(subparser):
    subparser.add_argument("wks_file")

    subparser.add_argument("-o", "--outdir", dest="outdir", default='.',
                      help="name of directory to create image in")
    subparser.add_argument("-e", "--image-name", dest="image_name",
                      help="name of the image to use the artifacts from "
                           "e.g. core-image-sato")
    subparser.add_argument("-r", "--rootfs-dir", action=RootfsArgAction,
                      help="path to the /rootfs dir to use as the "
                           ".wks rootfs source")
    subparser.add_argument("-b", "--bootimg-dir", dest="bootimg_dir",
                      help="path to the dir containing the boot artifacts "
                           "(e.g. /EFI or /syslinux dirs) to use as the "
                           ".wks bootimg source")
    subparser.add_argument("-k", "--kernel-dir", dest="kernel_dir",
                      help="path to the dir containing the kernel to use "
                           "in the .wks bootimg")
    subparser.add_argument("-n", "--native-sysroot", dest="native_sysroot",
                      help="path to the native sysroot containing the tools "
                           "to use to build the image")
    subparser.add_argument("-s", "--skip-build-check", dest="build_check",
                      action="store_false", default=True, help="skip the build check")
    subparser.add_argument("-f", "--build-rootfs", action="store_true", help="build rootfs")
    subparser.add_argument("-c", "--compress-with", choices=("gzip", "bzip2", "xz"),
                      dest='compressor',
                      help="compress image with specified compressor")
    subparser.add_argument("-m", "--bmap", action="store_true", help="generate .bmap")
    subparser.add_argument("--no-fstab-update" ,action="store_true",
                      help="Do not change fstab file.")
    subparser.add_argument("-v", "--vars", dest='vars_dir',
                      help="directory with <image>.env files that store "
                           "bitbake variables")
    subparser.add_argument("-D", "--debug", dest="debug", action="store_true",
                      default=False, help="output debug information")
    subparser.add_argument("-i", "--imager", dest="imager",
                      default="direct", help="the wic imager plugin")
    return


def wic_init_parser_list(subparser):
    subparser.add_argument("list_type",
                        help="can be 'images' or 'source-plugins' "
                             "to obtain a list. "
                             "If value is a valid .wks image file")
    subparser.add_argument("help_for", default=[], nargs='*',
                        help="If 'list_type' is a valid .wks image file "
                             "this value can be 'help' to show the help information "
                             "defined inside the .wks file")
    return

def imgtype(arg):
    """
    Custom type for ArgumentParser
    Converts path spec to named tuple: (image, partition, path)
    """
    image = arg
    part = path = None
    if ':' in image:
        image, part = image.split(':')
        if '/' in part:
            part, path = part.split('/', 1)
        if not path:
            path = '/'

    if not os.path.isfile(image):
        err = "%s is not a regular file or symlink" % image
        raise argparse.ArgumentTypeError(err)

    return namedtuple('ImgType', 'image part path')(image, part, path)

def wic_init_parser_ls(subparser):
    subparser.add_argument("path", type=imgtype,
                        help="image spec: <image>[:<vfat partition>[<path>]]")
    subparser.add_argument("-n", "--native-sysroot",
                        help="path to the native sysroot containing the tools")

def imgpathtype(arg):
    img = imgtype(arg)
    if img.part is None:
        raise argparse.ArgumentTypeError("partition number is not specified")
    return img

def wic_init_parser_cp(subparser):
    subparser.add_argument("src",
                        help="source spec")
    subparser.add_argument("dest", type=imgpathtype,
                        help="image spec: <image>:<vfat partition>[<path>]")
    subparser.add_argument("-n", "--native-sysroot",
                        help="path to the native sysroot containing the tools")

def wic_init_parser_rm(subparser):
    subparser.add_argument("path", type=imgpathtype,
                        help="path: <image>:<vfat partition><path>")
    subparser.add_argument("-n", "--native-sysroot",
                        help="path to the native sysroot containing the tools")

def expandtype(rules):
    """
    Custom type for ArgumentParser
    Converts expand rules to the dictionary {<partition>: size}
    """
    if rules == 'auto':
        return {}
    result = {}
    for rule in rules.split(','):
        try:
            part, size = rule.split(':')
        except ValueError:
            raise argparse.ArgumentTypeError("Incorrect rule format: %s" % rule)

        if not part.isdigit():
            raise argparse.ArgumentTypeError("Rule '%s': partition number must be integer" % rule)

        # validate size
        multiplier = 1
        for suffix, mult in [('K', 1024), ('M', 1024 * 1024), ('G', 1024 * 1024 * 1024)]:
            if size.upper().endswith(suffix):
                multiplier = mult
                size = size[:-1]
                break
        if not size.isdigit():
            raise argparse.ArgumentTypeError("Rule '%s': size must be integer" % rule)

        result[int(part)] = int(size) * multiplier

    return result

def wic_init_parser_write(subparser):
    subparser.add_argument("image",
                        help="path to the wic image")
    subparser.add_argument("target",
                        help="target file or device")
    subparser.add_argument("-e", "--expand", type=expandtype,
                        help="expand rules: auto or <partition>:<size>[,<partition>:<size>]")
    subparser.add_argument("-n", "--native-sysroot",
                        help="path to the native sysroot containing the tools")

def wic_init_parser_help(subparser):
    helpparsers = subparser.add_subparsers(dest='help_topic', help=hlp.wic_usage)
    for helptopic in helptopics:
        helpparsers.add_parser(helptopic, help=helptopics[helptopic][2])
    return


subcommands = {
    "create":    [wic_create_subcommand,
                  hlp.wic_create_usage,
                  hlp.wic_create_help,
                  wic_init_parser_create],
    "list":      [wic_list_subcommand,
                  hlp.wic_list_usage,
                  hlp.wic_list_help,
                  wic_init_parser_list],
    "ls":        [wic_ls_subcommand,
                  hlp.wic_ls_usage,
                  hlp.wic_ls_help,
                  wic_init_parser_ls],
    "cp":        [wic_cp_subcommand,
                  hlp.wic_cp_usage,
                  hlp.wic_cp_help,
                  wic_init_parser_cp],
    "rm":        [wic_rm_subcommand,
                  hlp.wic_rm_usage,
                  hlp.wic_rm_help,
                  wic_init_parser_rm],
    "write":     [wic_write_subcommand,
                  hlp.wic_write_usage,
                  hlp.wic_write_help,
                  wic_init_parser_write],
    "help":      [wic_help_subcommand,
                  wic_help_topic_usage,
                  hlp.wic_help_help,
                  wic_init_parser_help]
}


def init_parser(parser):
    parser.add_argument("--version", action="version",
        version="%(prog)s {version}".format(version=__version__))
    parser.add_argument("-D", "--debug", dest="debug", action="store_true",
        default=False, help="output debug information")

    subparsers = parser.add_subparsers(dest='command', help=hlp.wic_usage)
    for subcmd in subcommands:
        subparser = subparsers.add_parser(subcmd, help=subcommands[subcmd][2])
        subcommands[subcmd][3](subparser)

class WicArgumentParser(argparse.ArgumentParser):
     def format_help(self):
         return hlp.wic_help

def main(argv):
    parser = WicArgumentParser(
        description="wic version %s" % __version__)

    init_parser(parser)

    args = parser.parse_args(argv)

    if args.debug:
        logger.setLevel(logging.DEBUG)

    if "command" in vars(args):
        if args.command == "help":
            if args.help_topic is None:
                parser.print_help()
            elif args.help_topic in helptopics:
                hlpt = helptopics[args.help_topic]
                hlpt[0](hlpt[1], hlpt[2])
            return 0

    return hlp.invoke_subcommand(args, parser, hlp.wic_help_usage, subcommands)


if __name__ == "__main__":
    try:
        sys.exit(main(sys.argv[1:]))
    except WicError as err:
        print()
        logger.error(err)
        sys.exit(1)
