# 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
# This implements the 'direct' image creator class for 'wic'
#
# AUTHORS
# Tom Zanussi <tom.zanussi (at] linux.intel.com>
#

import os
import shutil

from wic import kickstart, msger
from wic.utils import fs_related
from wic.utils.oe.misc import get_bitbake_var
from wic.utils.partitionedfs import Image
from wic.utils.errors import CreatorError, ImageError
from wic.imager.baseimager import BaseImageCreator
from wic.plugin import pluginmgr
from wic.utils.oe.misc import exec_cmd

disk_methods = {
    "do_install_disk":None,
}

class DirectImageCreator(BaseImageCreator):
    """
    Installs a system into a file containing a partitioned disk image.

    DirectImageCreator is an advanced ImageCreator subclass; an image
    file is formatted with a partition table, each partition created
    from a rootfs or other OpenEmbedded build artifact and dd'ed into
    the virtual disk. The disk image can subsequently be dd'ed onto
    media and used on actual hardware.
    """

    def __init__(self, oe_builddir, image_output_dir, rootfs_dir, bootimg_dir,
                 kernel_dir, native_sysroot, compressor, creatoropts=None):
        """
        Initialize a DirectImageCreator instance.

        This method takes the same arguments as ImageCreator.__init__()
        """
        BaseImageCreator.__init__(self, creatoropts)

        self.__image = None
        self.__disks = {}
        self.__disk_format = "direct"
        self._disk_names = []
        self.ptable_format = self.ks.handler.bootloader.ptable

        self.oe_builddir = oe_builddir
        if image_output_dir:
            self.tmpdir = image_output_dir
        self.rootfs_dir = rootfs_dir
        self.bootimg_dir = bootimg_dir
        self.kernel_dir = kernel_dir
        self.native_sysroot = native_sysroot
        self.compressor = compressor

    def __get_part_num(self, num, parts):
        """calculate the real partition number, accounting for partitions not
        in the partition table and logical partitions
        """
        realnum = 0
        for pnum, part in enumerate(parts, 1):
            if not part.no_table:
                realnum += 1
            if pnum == num:
                if  part.no_table:
                    return 0
                if self.ptable_format == 'msdos' and realnum > 3:
                    # account for logical partition numbering, ex. sda5..
                    return realnum + 1
                return realnum

    def _write_fstab(self, image_rootfs):
        """overriden to generate fstab (temporarily) in rootfs. This is called
        from _create, make sure it doesn't get called from
        BaseImage.create()
        """
        if not image_rootfs:
            return

        fstab_path = image_rootfs + "/etc/fstab"
        if not os.path.isfile(fstab_path):
            return

        with open(fstab_path) as fstab:
            fstab_lines = fstab.readlines()

        if self._update_fstab(fstab_lines, self._get_parts()):
            shutil.copyfile(fstab_path, fstab_path + ".orig")

            with open(fstab_path, "w") as fstab:
                fstab.writelines(fstab_lines)

            return fstab_path

    def _update_fstab(self, fstab_lines, parts):
        """Assume partition order same as in wks"""
        updated = False
        for num, part in enumerate(parts, 1):
            pnum = self.__get_part_num(num, parts)
            if not pnum or not part.mountpoint \
               or part.mountpoint in ("/", "/boot"):
                continue

            # mmc device partitions are named mmcblk0p1, mmcblk0p2..
            prefix = 'p' if  part.disk.startswith('mmcblk') else ''
            device_name = "/dev/%s%s%d" % (part.disk, prefix, pnum)

            opts = part.fsopts if part.fsopts else "defaults"
            line = "\t".join([device_name, part.mountpoint, part.fstype,
                              opts, "0", "0"]) + "\n"

            fstab_lines.append(line)
            updated = True

        return updated

    def set_bootimg_dir(self, bootimg_dir):
        """
        Accessor for bootimg_dir, the actual location used for the source
        of the bootimg.  Should be set by source plugins (only if they
        change the default bootimg source) so the correct info gets
        displayed for print_outimage_info().
        """
        self.bootimg_dir = bootimg_dir

    def _get_parts(self):
        if not self.ks:
            raise CreatorError("Failed to get partition info, "
                               "please check your kickstart setting.")

        # Set a default partition if no partition is given out
        if not self.ks.handler.partition.partitions:
            partstr = "part / --size 1900 --ondisk sda --fstype=ext3"
            args = partstr.split()
            part = self.ks.handler.partition.parse(args[1:])
            if part not in self.ks.handler.partition.partitions:
                self.ks.handler.partition.partitions.append(part)

        # partitions list from kickstart file
        return kickstart.get_partitions(self.ks)

    def get_disk_names(self):
        """ Returns a list of physical target disk names (e.g., 'sdb') which
        will be created. """

        if self._disk_names:
            return self._disk_names

        #get partition info from ks handler
        parts = self._get_parts()

        for i in range(len(parts)):
            if parts[i].disk:
                disk_name = parts[i].disk
            else:
                raise CreatorError("Failed to create disks, no --ondisk "
                                   "specified in partition line of ks file")

            if parts[i].mountpoint and not parts[i].fstype:
                raise CreatorError("Failed to create disks, no --fstype "
                                   "specified for partition with mountpoint "
                                   "'%s' in the ks file")

            self._disk_names.append(disk_name)

        return self._disk_names

    def _full_name(self, name, extention):
        """ Construct full file name for a file we generate. """
        return "%s-%s.%s" % (self.name, name, extention)

    def _full_path(self, path, name, extention):
        """ Construct full file path to a file we generate. """
        return os.path.join(path, self._full_name(name, extention))

    def get_default_source_plugin(self):
        """
        The default source plugin i.e. the plugin that's consulted for
        overall image generation tasks outside of any particular
        partition.  For convenience, we just hang it off the
        bootloader handler since it's the one non-partition object in
        any setup.  By default the default plugin is set to the same
        plugin as the /boot partition; since we hang it off the
        bootloader object, the default can be explicitly set using the
        --source bootloader param.
        """
        return self.ks.handler.bootloader.source

    #
    # Actual implemention
    #
    def _create(self):
        """
        For 'wic', we already have our build artifacts - we just create
        filesystems from the artifacts directly and combine them into
        a partitioned image.
        """
        parts = self._get_parts()

        self.__image = Image(self.native_sysroot)

        for part in parts:
            # as a convenience, set source to the boot partition source
            # instead of forcing it to be set via bootloader --source
            if not self.ks.handler.bootloader.source and part.mountpoint == "/boot":
                self.ks.handler.bootloader.source = part.source

        fstab_path = self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))

        for part in parts:
            # get rootfs size from bitbake variable if it's not set in .ks file
            if not part.size:
                # and if rootfs name is specified for the partition
                image_name = part.get_rootfs()
                if image_name:
                    # Bitbake variable ROOTFS_SIZE is calculated in
                    # Image._get_rootfs_size method from meta/lib/oe/image.py
                    # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT,
                    # IMAGE_OVERHEAD_FACTOR and IMAGE_ROOTFS_EXTRA_SPACE
                    rsize_bb = get_bitbake_var('ROOTFS_SIZE', image_name)
                    if rsize_bb:
                        part.size = int(round(float(rsize_bb)))
            # need to create the filesystems in order to get their
            # sizes before we can add them and do the layout.
            # Image.create() actually calls __format_disks() to create
            # the disk images and carve out the partitions, then
            # self.assemble() calls Image.assemble() which calls
            # __write_partitition() for each partition to dd the fs
            # into the partitions.
            part.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir,
                         self.bootimg_dir, self.kernel_dir, self.native_sysroot)


            self.__image.add_partition(int(part.size),
                                       part.disk,
                                       part.mountpoint,
                                       part.source_file,
                                       part.fstype,
                                       part.label,
                                       fsopts=part.fsopts,
                                       boot=part.active,
                                       align=part.align,
                                       no_table=part.no_table,
                                       part_type=part.part_type,
                                       uuid=part.uuid)

        if fstab_path:
            shutil.move(fstab_path + ".orig", fstab_path)

        self.__image.layout_partitions(self.ptable_format)

        self.__imgdir = self.workdir
        for disk_name, disk in self.__image.disks.items():
            full_path = self._full_path(self.__imgdir, disk_name, "direct")
            msger.debug("Adding disk %s as %s with size %s bytes" \
                        % (disk_name, full_path, disk['min_size']))
            disk_obj = fs_related.DiskImage(full_path, disk['min_size'])
            self.__disks[disk_name] = disk_obj
            self.__image.add_disk(disk_name, disk_obj)

        self.__image.create()

    def assemble(self):
        """
        Assemble partitions into disk image(s)
        """
        for disk_name, disk in self.__image.disks.items():
            full_path = self._full_path(self.__imgdir, disk_name, "direct")
            msger.debug("Assembling disk %s as %s with size %s bytes" \
                        % (disk_name, full_path, disk['min_size']))
            self.__image.assemble(full_path)

    def finalize(self):
        """
        Finalize the disk image.

        For example, prepare the image to be bootable by e.g.
        creating and installing a bootloader configuration.

        """
        source_plugin = self.get_default_source_plugin()
        if source_plugin:
            self._source_methods = pluginmgr.get_source_plugin_methods(source_plugin, disk_methods)
            for disk_name, disk in self.__image.disks.items():
                self._source_methods["do_install_disk"](disk, disk_name, self,
                                                        self.workdir,
                                                        self.oe_builddir,
                                                        self.bootimg_dir,
                                                        self.kernel_dir,
                                                        self.native_sysroot)
        # Compress the image
        if self.compressor:
            for disk_name, disk in self.__image.disks.items():
                full_path = self._full_path(self.__imgdir, disk_name, "direct")
                msger.debug("Compressing disk %s with %s" % \
                            (disk_name, self.compressor))
                exec_cmd("%s %s" % (self.compressor, full_path))

    def print_outimage_info(self):
        """
        Print the image(s) and artifacts used, for the user.
        """
        msg = "The new image(s) can be found here:\n"

        parts = self._get_parts()

        for disk_name in self.__image.disks:
            extension = "direct" + {"gzip": ".gz",
                                    "bzip2": ".bz2",
                                    "xz": ".xz",
                                    "": ""}.get(self.compressor)
            full_path = self._full_path(self.__imgdir, disk_name, extension)
            msg += '  %s\n\n' % full_path

        msg += 'The following build artifacts were used to create the image(s):\n'
        for part in parts:
            if part.get_rootfs() is None:
                continue
            if part.mountpoint == '/':
                suffix = ':'
            else:
                suffix = '["%s"]:' % (part.mountpoint or part.label)
            msg += '  ROOTFS_DIR%s%s\n' % (suffix.ljust(20), part.get_rootfs())

        msg += '  BOOTIMG_DIR:                  %s\n' % self.bootimg_dir
        msg += '  KERNEL_DIR:                   %s\n' % self.kernel_dir
        msg += '  NATIVE_SYSROOT:               %s\n' % self.native_sysroot

        msger.info(msg)

    @property
    def rootdev(self):
        """
        Get root device name to use as a 'root' parameter
        in kernel command line.

        Assume partition order same as in wks
        """
        parts = self._get_parts()
        for num, part in enumerate(parts, 1):
            if part.mountpoint == "/":
                if part.uuid:
                    return "PARTUUID=%s" % part.uuid
                else:
                    suffix = 'p' if part.disk.startswith('mmcblk') else ''
                    pnum = self.__get_part_num(num, parts)
                    return "/dev/%s%s%-d" % (part.disk, suffix, pnum)

    def _cleanup(self):
        if not self.__image is None:
            try:
                self.__image.cleanup()
            except ImageError, err:
                msger.warning("%s" % err)

