#!/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 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)
