#!/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")
    subparser.add_argument("-r", dest="recursive_delete", action="store_true", default=False,
                        help="remove directories and their contents recursively, "
                        " this only applies to ext* partition")

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)
