#!/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
import shutil

from collections import namedtuple

# 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 = shutil.which('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 options.kernel_dir:
        kernel_dir = options.kernel_dir

    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("-w", "--workdir",
                      help="temporary workdir to use for intermediate files")
    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")
    subparser.add_argument("--extra-space", type=int, dest="extra_space",
                      default=0, help="additional free disk space to add to the image")
    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="image spec: <image>:<vfat partition>[<path>] or <file>")
    subparser.add_argument("dest",
                        help="image spec: <image>:<vfat partition>[<path>] or <file>")
    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

    # validate wic cp src and dest parameter to identify which one of it is
    # image and cast it into imgtype
    if args.command == "cp":
        if ":" in args.dest:
            args.dest = imgtype(args.dest)
        elif ":" in args.src:
            args.src = imgtype(args.src)
        else:
            raise argparse.ArgumentTypeError("no image or partition number specified.")

    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)
