#
# Migration test command line shell integration
#
# Copyright (c) 2016 Red Hat, Inc.
#
# This library 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 of the License, or (at your option) any later version.
#
# This library 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 this library; if not, see <http://www.gnu.org/licenses/>.
#


import argparse
import fnmatch
import os
import os.path
import platform
import sys

from guestperf.hardware import Hardware
from guestperf.engine import Engine
from guestperf.scenario import Scenario
from guestperf.comparison import COMPARISONS
from guestperf.plot import Plot
from guestperf.report import Report


class BaseShell(object):

    def __init__(self):
        parser = argparse.ArgumentParser(description="Migration Test Tool")

        # Test args
        parser.add_argument("--debug", dest="debug", default=False, action="store_true")
        parser.add_argument("--verbose", dest="verbose", default=False, action="store_true")
        parser.add_argument("--sleep", dest="sleep", default=15, type=int)
        parser.add_argument("--binary", dest="binary", default="/usr/bin/qemu-system-x86_64")
        parser.add_argument("--dst-host", dest="dst_host", default="localhost")
        parser.add_argument("--kernel", dest="kernel", default="/boot/vmlinuz-%s" % platform.release())
        parser.add_argument("--initrd", dest="initrd", default="tests/migration/initrd-stress.img")
        parser.add_argument("--transport", dest="transport", default="unix")


        # Hardware args
        parser.add_argument("--cpus", dest="cpus", default=1, type=int)
        parser.add_argument("--mem", dest="mem", default=1, type=int)
        parser.add_argument("--src-cpu-bind", dest="src_cpu_bind", default="")
        parser.add_argument("--src-mem-bind", dest="src_mem_bind", default="")
        parser.add_argument("--dst-cpu-bind", dest="dst_cpu_bind", default="")
        parser.add_argument("--dst-mem-bind", dest="dst_mem_bind", default="")
        parser.add_argument("--prealloc-pages", dest="prealloc_pages", default=False)
        parser.add_argument("--huge-pages", dest="huge_pages", default=False)
        parser.add_argument("--locked-pages", dest="locked_pages", default=False)

        self._parser = parser

    def get_engine(self, args):
        return Engine(binary=args.binary,
                      dst_host=args.dst_host,
                      kernel=args.kernel,
                      initrd=args.initrd,
                      transport=args.transport,
                      sleep=args.sleep,
                      debug=args.debug,
                      verbose=args.verbose)

    def get_hardware(self, args):
        def split_map(value):
            if value == "":
                return []
            return value.split(",")

        return Hardware(cpus=args.cpus,
                        mem=args.mem,

                        src_cpu_bind=split_map(args.src_cpu_bind),
                        src_mem_bind=split_map(args.src_mem_bind),
                        dst_cpu_bind=split_map(args.dst_cpu_bind),
                        dst_mem_bind=split_map(args.dst_mem_bind),

                        locked_pages=args.locked_pages,
                        huge_pages=args.huge_pages,
                        prealloc_pages=args.prealloc_pages)


class Shell(BaseShell):

    def __init__(self):
        super(Shell, self).__init__()

        parser = self._parser

        parser.add_argument("--output", dest="output", default=None)

        # Scenario args
        parser.add_argument("--max-iters", dest="max_iters", default=30, type=int)
        parser.add_argument("--max-time", dest="max_time", default=300, type=int)
        parser.add_argument("--bandwidth", dest="bandwidth", default=125000, type=int)
        parser.add_argument("--downtime", dest="downtime", default=500, type=int)

        parser.add_argument("--pause", dest="pause", default=False, action="store_true")
        parser.add_argument("--pause-iters", dest="pause_iters", default=5, type=int)

        parser.add_argument("--post-copy", dest="post_copy", default=False, action="store_true")
        parser.add_argument("--post-copy-iters", dest="post_copy_iters", default=5, type=int)

        parser.add_argument("--auto-converge", dest="auto_converge", default=False, action="store_true")
        parser.add_argument("--auto-converge-step", dest="auto_converge_step", default=10, type=int)

        parser.add_argument("--compression-mt", dest="compression_mt", default=False, action="store_true")
        parser.add_argument("--compression-mt-threads", dest="compression_mt_threads", default=1, type=int)

        parser.add_argument("--compression-xbzrle", dest="compression_xbzrle", default=False, action="store_true")
        parser.add_argument("--compression-xbzrle-cache", dest="compression_xbzrle_cache", default=10, type=int)

    def get_scenario(self, args):
        return Scenario(name="perfreport",
                        downtime=args.downtime,
                        bandwidth=args.bandwidth,
                        max_iters=args.max_iters,
                        max_time=args.max_time,

                        pause=args.pause,
                        pause_iters=args.pause_iters,

                        post_copy=args.post_copy,
                        post_copy_iters=args.post_copy_iters,

                        auto_converge=args.auto_converge,
                        auto_converge_step=args.auto_converge_step,

                        compression_mt=args.compression_mt,
                        compression_mt_threads=args.compression_mt_threads,

                        compression_xbzrle=args.compression_xbzrle,
                        compression_xbzrle_cache=args.compression_xbzrle_cache)

    def run(self, argv):
        args = self._parser.parse_args(argv)

        engine = self.get_engine(args)
        hardware = self.get_hardware(args)
        scenario = self.get_scenario(args)

        try:
            report = engine.run(hardware, scenario)
            if args.output is None:
                print report.to_json()
            else:
                with open(args.output, "w") as fh:
                    print >>fh, report.to_json()
            return 0
        except Exception as e:
            print >>sys.stderr, "Error: %s" % str(e)
            if args.debug:
                raise
            return 1


class BatchShell(BaseShell):

    def __init__(self):
        super(BatchShell, self).__init__()

        parser = self._parser

        parser.add_argument("--filter", dest="filter", default="*")
        parser.add_argument("--output", dest="output", default=os.getcwd())

    def run(self, argv):
        args = self._parser.parse_args(argv)

        engine = self.get_engine(args)
        hardware = self.get_hardware(args)

        try:
            for comparison in COMPARISONS:
                compdir = os.path.join(args.output, comparison._name)
                for scenario in comparison._scenarios:
                    name = os.path.join(comparison._name, scenario._name)
                    if not fnmatch.fnmatch(name, args.filter):
                        if args.verbose:
                            print "Skipping %s" % name
                        continue

                    if args.verbose:
                        print "Running %s" % name

                    dirname = os.path.join(args.output, comparison._name)
                    filename = os.path.join(dirname, scenario._name + ".json")
                    if not os.path.exists(dirname):
                        os.makedirs(dirname)
                    report = engine.run(hardware, scenario)
                    with open(filename, "w") as fh:
                        print >>fh, report.to_json()
        except Exception as e:
            print >>sys.stderr, "Error: %s" % str(e)
            if args.debug:
                raise


class PlotShell(object):

    def __init__(self):
        super(PlotShell, self).__init__()

        self._parser = argparse.ArgumentParser(description="Migration Test Tool")

        self._parser.add_argument("--output", dest="output", default=None)

        self._parser.add_argument("--debug", dest="debug", default=False, action="store_true")
        self._parser.add_argument("--verbose", dest="verbose", default=False, action="store_true")

        self._parser.add_argument("--migration-iters", dest="migration_iters", default=False, action="store_true")
        self._parser.add_argument("--total-guest-cpu", dest="total_guest_cpu", default=False, action="store_true")
        self._parser.add_argument("--split-guest-cpu", dest="split_guest_cpu", default=False, action="store_true")
        self._parser.add_argument("--qemu-cpu", dest="qemu_cpu", default=False, action="store_true")
        self._parser.add_argument("--vcpu-cpu", dest="vcpu_cpu", default=False, action="store_true")

        self._parser.add_argument("reports", nargs='*')

    def run(self, argv):
        args = self._parser.parse_args(argv)

        if len(args.reports) == 0:
            print >>sys.stderr, "At least one report required"
            return 1

        if not (args.qemu_cpu or
                args.vcpu_cpu or
                args.total_guest_cpu or
                args.split_guest_cpu):
            print >>sys.stderr, "At least one chart type is required"
            return 1

        reports = []
        for report in args.reports:
            reports.append(Report.from_json_file(report))

        plot = Plot(reports,
                    args.migration_iters,
                    args.total_guest_cpu,
                    args.split_guest_cpu,
                    args.qemu_cpu,
                    args.vcpu_cpu)

        plot.generate(args.output)
