#!/usr/bin/env python
# This file is part of Cockpit.
#
# Copyright (C) 2013 Red Hat, Inc.
#
# Cockpit is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Cockpit 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.

import argparse
import os
import sys
import subprocess

import testvm
import testinfra

parser = argparse.ArgumentParser(description='Install Cockpit on a virtual machine')
parser.add_argument('-v', '--verbose', action='store_true', help='Display verbose progress details')
parser.add_argument('-q', '--quick', action='store_true', help='Build faster')
parser.add_argument('-b', '--build-image', action='store', help='Build in this image')
parser.add_argument('-B', '--build-only', action='store_true', help='Only build and download results')
parser.add_argument('-I', '--install-only', action='store_true', help='Only upload and install')
parser.add_argument('-c', '--containers', action='store_true', help='Install container images')
parser.add_argument('image', nargs='?', default=testinfra.DEFAULT_IMAGE, help='The image to use')
args = parser.parse_args()

install_image = not args.build_only and args.image
build_image = not args.install_only and (args.build_image or args.image)

def upload_scripts(machine):
    machine.execute("rm -rf /var/lib/testvm")
    machine.upload([ "guest/lib" ], "/var/lib/testvm")
    machine.upload([ "./guest/%s.install" % machine.image ], "/var/tmp")
    if args.containers:
        machine.upload(["../images"], "/var/tmp")

def run_install_script(machine, do_build, do_install, skip, arg):
    install = do_install
    if args.containers:
        do_install = False

    machine.execute("cd /var/tmp; ./%s.install%s%s%s%s%s%s" % (machine.image,
                                                         " --verbose" if args.verbose else "",
                                                         " --quick" if args.quick else "",
                                                         " --build" if do_build else "",
                                                         " --install" if do_install else "",
                                                         " --skip '%s'" % skip if skip else "",
                                                         " '%s'" % arg if arg else ""))
    if install and args.containers:
        machine.execute("/var/lib/testvm/containers.install")

def build_and_maybe_install(image, do_install=False, skip=None):
    """Build and maybe install Cockpit into a test image"""
    machine = testvm.VirtMachine(verbose=args.verbose, image=image, label="install")
    source = subprocess.check_output([ "../tools/make-source" ]).strip()
    machine.start(maintain=do_install, memory_mb=4096, cpus=4)
    try:
        machine.wait_boot()
        upload_scripts(machine)
        machine.upload([ source ], "/var/tmp")
        run_install_script(machine, True, do_install, skip, os.path.basename(source))
    finally:
        try:
            machine.download_dir("/var/tmp/build-results", "tmp/build-results")
        finally:
            machine.stop()

def only_install(image, skip=None):
    """Install Cockpit into a test image"""
    machine = testvm.VirtMachine(verbose=args.verbose, image=image, label="install")
    machine.start(maintain=True)
    try:
        machine.wait_boot()
        upload_scripts(machine)
        machine.execute("rm -rf /var/tmp/build-results");
        machine.upload([ "tmp/build-results" ], "/var/tmp")
        run_install_script(machine, False, True, skip, None)
    finally:
        machine.stop()

try:
    skip = "cockpit-ostree"
    if "fedora-atomic" in install_image:
        skip = None

    if build_image and build_image == install_image:
        build_and_maybe_install(build_image, do_install=True, skip=skip)
    else:
        if build_image:
            build_and_maybe_install(build_image, do_install=False, skip=skip)
        if install_image:
            only_install(install_image, skip)
except testvm.Failure, ex:
    print >> sys.stderr, "vm-install:", ex
    sys.exit(1)
