# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# This program is free software; you can distribute 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 mo 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.
#
# AUTHOR
# Adrian Freihofer <adrian.freihofer (at] neratec.com>
#

import os
from wic import kickstart
from wic import msger
from wic.utils import syslinux
from wic.utils import runner
from wic.utils.oe import misc
from wic.utils.errors import ImageError
from wic.pluginbase import SourcePlugin


# pylint: disable=no-init
class RootfsPlugin(SourcePlugin):
    """
    Create root partition and install syslinux bootloader

    This plugin creates a disk image containing a bootable root partition with
    syslinux installed. The filesystem is ext2/3/4, no extra boot partition is
    required.

    Example kickstart file:
    part / --source rootfs-pcbios-ext --ondisk sda --fstype=ext4 --label rootfs --align 1024
    bootloader --source rootfs-pcbios-ext --timeout=0 --append="rootwait rootfstype=ext4"

    The first line generates a root file system including a syslinux.cfg file
    The "--source rootfs-pcbios-ext" in the second line triggers the installation
    of ldlinux.sys into the image.
    """

    name = 'rootfs-pcbios-ext'

    @staticmethod
    def _get_rootfs_dir(rootfs_dir):
        """
        Find rootfs pseudo dir

        If rootfs_dir is a directory consider it as rootfs directory.
        Otherwise ask bitbake about the IMAGE_ROOTFS directory.
        """
        if os.path.isdir(rootfs_dir):
            return rootfs_dir

        image_rootfs_dir = misc.get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
        if not os.path.isdir(image_rootfs_dir):
            msg = "No valid artifact IMAGE_ROOTFS from image named"
            msg += " %s has been found at %s, exiting.\n" % \
                (rootfs_dir, image_rootfs_dir)
            msger.error(msg)

        return image_rootfs_dir

    # pylint: disable=unused-argument
    @classmethod
    def do_configure_partition(cls, part, source_params, image_creator,
                               image_creator_workdir, oe_builddir, bootimg_dir,
                               kernel_dir, native_sysroot):
        """
        Creates syslinux config in rootfs directory

        Called before do_prepare_partition()
        """
        options = image_creator.ks.handler.bootloader.appendLine

        syslinux_conf = ""
        syslinux_conf += "PROMPT 0\n"

        timeout = kickstart.get_timeout(image_creator.ks)
        if not timeout:
            timeout = 0
        syslinux_conf += "TIMEOUT " + str(timeout) + "\n"
        syslinux_conf += "ALLOWOPTIONS 1\n"

        # Derive SERIAL... line from from kernel boot parameters
        syslinux_conf += syslinux.serial_console_form_kargs(options) + "\n"

        syslinux_conf += "DEFAULT linux\n"
        syslinux_conf += "LABEL linux\n"
        syslinux_conf += "  KERNEL /boot/bzImage\n"

        syslinux_conf += "  APPEND label=boot root=%s %s\n" % \
                             (image_creator.rootdev, options)

        syslinux_cfg = os.path.join(image_creator.rootfs_dir['ROOTFS_DIR'], "boot", "syslinux.cfg")
        msger.debug("Writing syslinux config %s" % syslinux_cfg)
        with open(syslinux_cfg, "w") as cfg:
            cfg.write(syslinux_conf)

    @classmethod
    def do_prepare_partition(cls, part, source_params, image_creator,
                             image_creator_workdir, oe_builddir, bootimg_dir,
                             kernel_dir, krootfs_dir, native_sysroot):
        """
        Creates partition out of rootfs directory

        Prepare content for a rootfs partition i.e. create a partition
        and fill it from a /rootfs dir.
        Install syslinux bootloader into root partition image file
        """
        def is_exe(exepath):
            """Verify exepath is an executable file"""
            return os.path.isfile(exepath) and os.access(exepath, os.X_OK)

        # Make sure syslinux-nomtools is available in native sysroot or fail
        native_syslinux_nomtools = os.path.join(native_sysroot, "usr/bin/syslinux-nomtools")
        if not is_exe(native_syslinux_nomtools):
            msger.info("building syslinux-native...")
            misc.exec_cmd("bitbake syslinux-native")
        if not is_exe(native_syslinux_nomtools):
            msger.error("Couldn't find syslinux-nomtools (%s), exiting\n" %
                        native_syslinux_nomtools)

        if part.rootfs is None:
            if 'ROOTFS_DIR' not in krootfs_dir:
                msger.error("Couldn't find --rootfs-dir, exiting")
            rootfs_dir = krootfs_dir['ROOTFS_DIR']
        else:
            if part.rootfs in krootfs_dir:
                rootfs_dir = krootfs_dir[part.rootfs]
            elif part.rootfs:
                rootfs_dir = part.rootfs
            else:
                msg = "Couldn't find --rootfs-dir=%s connection"
                msg += " or it is not a valid path, exiting"
                msger.error(msg % part.rootfs)

        real_rootfs_dir = cls._get_rootfs_dir(rootfs_dir)

        part.set_rootfs(real_rootfs_dir)
        part.prepare_rootfs(image_creator_workdir, oe_builddir, real_rootfs_dir, native_sysroot)

        # install syslinux into rootfs partition
        syslinux_cmd = "syslinux-nomtools -d /boot -i %s" % part.source_file
        misc.exec_native_cmd(syslinux_cmd, native_sysroot)

    @classmethod
    def do_install_disk(cls, disk, disk_name, image_creator, workdir, oe_builddir,
                        bootimg_dir, kernel_dir, native_sysroot):
        """
        Assemble partitions to disk image

        Called after all partitions have been prepared and assembled into a
        disk image. In this case, we install the MBR.
        """
        mbrfile = os.path.join(native_sysroot, "usr/share/syslinux/")
        if image_creator.ptable_format == 'msdos':
            mbrfile += "mbr.bin"
        elif image_creator.ptable_format == 'gpt':
            mbrfile += "gptmbr.bin"
        else:
            msger.error("Unsupported partition table: %s" % \
                        image_creator.ptable_format)

        if not os.path.exists(mbrfile):
            msger.error("Couldn't find %s. Has syslinux-native been baked?" % mbrfile)

        full_path = disk['disk'].device
        msger.debug("Installing MBR on disk %s as %s with size %s bytes" \
                    % (disk_name, full_path, disk['min_size']))

        ret_code = runner.show(['dd', 'if=%s' % mbrfile, 'of=%s' % full_path, 'conv=notrunc'])
        if ret_code != 0:
            raise ImageError("Unable to set MBR to %s" % full_path)
