#!/usr/bin/env python3
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (c) 2013, Intel Corporation.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# 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

from collections import namedtuple
from distutils import spawn

# External modules
scripts_path = os.path.abspath(os.path.dirname(__file__))
lib_path = scripts_path + '/lib'
sys.path.insert(0, lib_path)
oe_lib_path = os.path.join(os.path.dirname(scripts_path), 'meta', 'lib')
sys.path.insert(0, oe_lib_path)

bitbake_exe = spawn.find_executable('bitbake')
if bitbake_exe:
    bitbake_path = os.path.join(os.path.dirname(bitbake_exe), '../lib')
    sys.path.insert(0, bitbake_path)
    from bb import cookerdata
    from bb.main import bitbake_main, BitBakeConfigParameters
else:
    bitbake_main = None

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_main:
        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")
            if bitbake_main(BitBakeConfigParameters(argv),
                            cookerdata.CookerConfiguration()):
                raise WicError("bitbake exited with error")

        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")
        if bitbake_main(BitBakeConfigParameters("bitbake wic-tools".split()),
                        cookerdata.CookerConfiguration()):
            raise WicError("bitbake wic-tools failed")
        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")
    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__))
    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)


def main(argv):
    parser = argparse.ArgumentParser(
        description="wic version %s" % __version__)

    init_parser(parser)

    args = parser.parse_args(argv)

    if "command" in vars(args):
        if args.command == "help":
            if args.help_topic is None:
                parser.print_help()
                print()
                print("Please specify a help topic")
            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)
