import os
import sys
import errno
import datetime
import itertools
from commands import runCmd

def get_host_dumper(d):
    cmds = d.getVar("testimage_dump_host", True)
    parent_dir = d.getVar("TESTIMAGE_DUMP_DIR", True)
    return HostDumper(cmds, parent_dir)


class BaseDumper(object):
    """ Base class to dump commands from host/target """

    def __init__(self, cmds, parent_dir):
        self.cmds = []
        # Some testing doesn't inherit testimage, so it is needed
        # to set some defaults.
        self.parent_dir = parent_dir or "/tmp/oe-saved-tests"
        dft_cmds = """  top -bn1
                        iostat -x -z -N -d -p ALL 20 2
                        ps -ef
                        free
                        df
                        memstat
                        dmesg
                        ip -s link
                        netstat -an"""
        if not cmds:
            cmds = dft_cmds
        for cmd in cmds.split('\n'):
            cmd = cmd.lstrip()
            if not cmd or cmd[0] == '#':
                continue
            self.cmds.append(cmd)

    def create_dir(self, dir_suffix):
        dump_subdir = ("%s_%s" % (
                datetime.datetime.now().strftime('%Y%m%d%H%M'),
                dir_suffix))
        dump_dir = os.path.join(self.parent_dir, dump_subdir)
        try:
            os.makedirs(dump_dir)
        except OSError as err:
            if err.errno != errno.EEXIST:
                raise err
        self.dump_dir = dump_dir

    def _write_dump(self, command, output):
        if isinstance(self, HostDumper):
            prefix = "host"
        elif isinstance(self, TargetDumper):
            prefix = "target"
        else:
            prefix = "unknown"
        for i in itertools.count():
            filename = "%s_%02d_%s" % (prefix, i, command)
            fullname = os.path.join(self.dump_dir, filename)
            if not os.path.exists(fullname):
                break
        with open(fullname, 'w') as dump_file:
            dump_file.write(output)


class HostDumper(BaseDumper):
    """ Class to get dumps from the host running the tests """

    def __init__(self, cmds, parent_dir):
        super(HostDumper, self).__init__(cmds, parent_dir)

    def dump_host(self, dump_dir=""):
        if dump_dir:
            self.dump_dir = dump_dir
        for cmd in self.cmds:
            result = runCmd(cmd, ignore_status=True)
            self._write_dump(cmd.split()[0], result.output)


class TargetDumper(BaseDumper):
    """ Class to get dumps from target, it only works with QemuRunner """

    def __init__(self, cmds, parent_dir, qemurunner):
        super(TargetDumper, self).__init__(cmds, parent_dir)
        self.runner = qemurunner

    def dump_target(self, dump_dir=""):
        if dump_dir:
            self.dump_dir = dump_dir
        for cmd in self.cmds:
            # We can continue with the testing if serial commands fail
            try:
                (status, output) = self.runner.run_serial(cmd)
                self._write_dump(cmd.split()[0], output)
            except:
                print("Tried to dump info from target but "
                        "serial console failed")
