#!/usr/bin/env python

# live-wrapper - Wrapper for vmdebootstrap for creating live images
# (C) Iain R. Learmonth 2015 <irl@debian.org>
# See COPYING for terms of usage, modification and redistribution.
#
# bin/lwr - Live Wrapper (Application)

"""
This script is the main script for the live-wrapper application. It is
intended to be run from the command line.

See live-wrapper(8) for more information.
"""

import sys
import os
import cliapp
import logging
from pycurl import Curl
from tarfile import TarFile
from lbng.vm import VMDebootstrap
from lbng.isolinux import install_isolinux
from lbng.disk import install_disk_info
from lbng.grub import install_grub
from lbng.xorriso import Xorriso

__version__ = '0.1'

DI_HELPERS = 'http://ftp.debian.org/debian/dists/stretch/main/installer-amd64/current/images/cdrom/debian-cd_info.tar.gz' # pylint: disable=line-too-long

def fetch_di_helpers():
    with open('info.tar.gz', 'w') as info:
        curl = Curl()
        curl.setopt(curl.URL, DI_HELPERS)
        curl.setopt(curl.WRITEDATA, info)
        curl.perform()
        curl.close()
    info = TarFile.open('info.tar.gz', 'r:gz')
    if not os.path.exists('cdhelp'):
        os.mkdir('cdhelp')
    info.extractall(path='cdhelp/')
    info.close()


class LiveBuildNG(cliapp.Application):

    def add_settings(self):
        self.settings.string(
            ['o', 'image_output'], 'Location for built image',
            metavar='/PATH/TO/FILE.ISO',
            default='live.iso', group='Base Settings')
        self.settings.string(
            ['d', 'distribution'], 'Debian release to use (default: %default)',
            metavar='NAME',
            default='stable', group='Base Settings')
        self.settings.string(
            ['m', 'mirror'], 'Mirror to use for image creation',
            metavar='MIRROR',
            group='Base Settings')
        self.settings.string(
            ['t', 'tasks'], 'Task packages to install',
            metavar='"task-TASK1 task-TASK2 ..."',
            group='Packages')
        self.settings.string(
            ['e', 'extra'], 'Extra packages to install',
            metavar='"PKG1 PKG2 ..."',
            group='Packages')
        self.settings.boolean(
            ['isolinux'], 'Add isolinux bootloader to the image '
            '(default: %default)', default=True, group="Bootloaders")
        self.settings.boolean(
            ['grub'], 'Add GRUB bootloader to the image (for EFI support) '
            '(default: %default)', default=True, group="Bootloaders")
        self.settings.boolean(
            ['grub-loopback-only'], 'Only install the loopback.cfg GRUB '
            'configuration (for loopback support) (overrides --grub) '
            '(default: %default)', default=False, group="Bootloaders")


    def process_args(self, args):
        if not self.settings['isolinux'] and not self.settings['grub']:
            cliapp.AppException("You must enable at least one bootloader!")
        if self.settings['grub'] and self.settings['grub-loopback-only']:
            self.settings['grub'] = False
        if os.geteuid() != 0:
            sys.exit("You need to have root privileges to run this script.")
        self.start_ops()

    def start_ops(self):
        """
        This function creates the live image using the settings determined by
        the arguments passed on the command line.

        .. note::
            This function is called by process_args() once all the arguments
            have been validated.
        """

        #Create work directory
        if not os.path.exists("cdroot"):
            os.mkdir("cdroot")
        else:
            cliapp.AppException("A cdroot directory already exists. Please "
                                "remove before building a fresh image.")

        #Make options available to customise hook in vmdebootstrap
        os.environ['LBNG_TASK_PACKAGES'] = self.settings['tasks']
        os.environ['LBNG_EXTRA_PACKAGES'] = self.settings['extra']
        if self.settings['mirror'] == "":
            os.environ['MIRROR'] = self.settings['mirror']

        #Run vmdebootstrap
        vm = VMDebootstrap(self.settings['distribution'],
                           self.settings['mirror'])
        vm.run()

        #Fetch D-I helper archive if needed
        if self.settings['grub']:
            fetch_di_helpers()

        #Install isolinux if selected
        if self.settings['isolinux']:
            install_isolinux('cdroot')

        #Install GRUB if selected
        if self.settings['grub'] or self.settings['grub-loopback-only']:
            install_grub('cdroot', 'cdhelp')

        #Install .disk information
        install_disk_info()

        #Create ISO image
        xorriso = Xorriso(self.settings['image_output'],
                          isolinux=self.settings['isolinux'],
                          grub=self.settings['grub'])
        xorriso.build_args()
        xorriso.build_image()

if __name__ == "__main__":
    LiveBuildNG(version=__version__).run()
