import sys, os, re, string
from autotest_lib.client.bin import utils, fsinfo, fsdev_mgr, partition
from autotest_lib.client.common_lib import error


fd_mgr = fsdev_mgr.FsdevManager()

# For unmounting / formatting file systems we may have to use a device name
# that is different from the real device name that we have to use to set I/O
# scheduler tunables.
_DISKPART_FILE = '/proc/partitions'


def get_disk_list(std_mounts_only=True, get_all_disks=False):
    """
    Get a list of dictionaries with information about disks on this system.

    @param std_mounts_only: Whether the function should return only disks that
            have a mount point defined (True) or even devices that doesn't
            (False).

    @param get_all_disks: Whether the function should return only partitioned
            disks (False) or return every disk, regardless of being partitioned
            or not (True).

    @return: List of dictionaries with disk information (see more below).

    The 'disk_list' array returned by get_disk_list() has an entry for each
    disk drive we find on the box. Each of these entries is a map with the
    following 3 string values:

        'device'      disk device name (i.e. the part after /dev/)
        'mountpt'     disk mount path
        'tunable'     disk name for setting scheduler tunables (/sys/block/sd??)

    The last value is an integer that indicates the current mount status
    of the drive:

        'mounted'     0 = not currently mounted
                      1 = mounted r/w on the expected path
                     -1 = mounted readonly or at an unexpected path

    When the 'std_mounts_only' argument is True we don't include drives
    mounted on 'unusual' mount points in the result. If a given device is
    partitioned, it will return all partitions that exist on it. If it's not,
    it will return the device itself (ie, if there are /dev/sdb1 and /dev/sdb2,
    those will be returned but not /dev/sdb. if there is only a /dev/sdc, that
    one will be returned).
    """
    # Get hold of the currently mounted file systems
    mounts = utils.system_output('mount').splitlines()

    # Grab all the interesting disk partition names from /proc/partitions,
    # and build up the table of drives present in the system.
    hd_list   = []
    # h for IDE drives, s for SATA/SCSI drives, v for Virtio drives
    hd_regexp = re.compile("([hsv]d[a-z]+3)$")

    partfile  = open(_DISKPART_FILE)
    for partline in partfile:
        parts = partline.strip().split()
        if len(parts) != 4 or partline.startswith('major'):
            continue

        # Get hold of the partition name
        partname = parts[3]

        if not get_all_disks:
            # The partition name better end with a digit
            # (get only partitioned disks)
            if not partname[-1:].isdigit():
                continue

        # Process any site-specific filters on the partition name
        if not fd_mgr.use_partition(partname):
            continue

        # We need to know the IDE/SATA/... device name for setting tunables
        tunepath = fd_mgr.map_drive_name(partname)

        # Check whether the device is mounted (and how)
        mstat  = 0
        fstype = ''
        fsopts = ''
        fsmkfs = '?'
        # Prepare the full device path for matching
        chkdev  = '/dev/' + partname

        mountpt = None
        for mln in mounts:
            splt = mln.split()

            # Typical 'mount' output line looks like this (indices
            # for the split() result shown below):
            #
            #    <device> on <mount_point> type <fstp> <options>
            #    0        1  2             3    4      5

            if splt[0].strip() == chkdev.strip():

                # Make sure the mount point looks reasonable
                mountpt = fd_mgr.check_mount_point(partname, splt[2])
                if not mountpt:
                    mstat = -1
                    break

                # Grab the file system type and mount options
                fstype = splt[4]
                fsopts = splt[5]

                # Check for something other than a r/w mount
                if fsopts[:3] != '(rw':
                    mstat = -1
                    break
                # The drive is mounted at the 'normal' mount point
                mstat = 1

        # Does the caller only want to allow 'standard' mount points?
        if std_mounts_only and mstat < 0:
            continue

        device_name = ''

        if not get_all_disks:
            # Was this partition mounted at all?
            if not mountpt:
                mountpt = fd_mgr.check_mount_point(partname, None)
                # Ask the client where we should mount this partition
                if not mountpt:
                    continue
        else:
            if partname[-1:].isdigit():
                device_name = re.sub("\d", "", "/dev/%s" % partname)

        if get_all_disks:
            if not device_name:
                continue

        # Looks like we have a valid disk drive, add it to the list
        hd_list.append({ 'device' : partname,
                         'mountpt': mountpt,
                         'tunable': tunepath,
                         'fs_type': fstype,
                         'fs_opts': fsopts,
                         'fs_mkfs': fsmkfs,
                         'mounted': mstat })

    return hd_list


def mkfs_all_disks(job, disk_list, fs_type, fs_makeopt, fs_mnt_opt):
    """
    Prepare all the drives in 'disk_list' for testing. For each disk this means
    unmounting any mount points that use the disk, running mkfs with 'fs_type'
    as the file system type and 'fs_makeopt' as the 'mkfs' options, and finally
    remounting the freshly formatted drive using the flags in 'fs_mnt_opt'.
    """

    for disk in disk_list:

        # For now, ext4 isn't quite ready for prime time
        if fs_type == "ext4":
            fs_type = "ext4dev"

        # Grab the device and mount paths for the drive
        dev_path = os.path.join('/dev', disk["device"])
        mnt_path = disk['mountpt']

        # Create a file system instance
        try:
            fs = job.filesystem(device=dev_path, mountpoint=mnt_path)
        except:
            raise Exception("Could not create a filesystem on '%s'" % dev_path)

        # Make sure the volume is unmounted
        if disk["mounted"]:
            try:
                fs.unmount(mnt_path)
            except Exception, info:
                raise Exception("umount failed: exception = %s, args = %s" %
                                               (sys.exc_info()[0], info.args))
            except:
                raise Exception("Could not unmount device ", dev_path)

        # Is the drive already formatted with the right file system?
        skip_mkfs = match_fs(disk, dev_path, fs_type, fs_makeopt)

        # Next step is to create a fresh file system (if we need to)
        try:
            if not skip_mkfs:
                fs.mkfs(fstype = fs_type, args = fs_makeopt)
        except:
            raise Exception("Could not 'mkfs " + "-t " + fs_type + " " +
                                       fs_makeopt + " " + dev_path + "'")

        # Mount the drive with the appropriate FS options
        try:
            opts = ""
            if fs_mnt_opt != "":
                opts += " -o " + fs_mnt_opt
            fs.mount(mountpoint = mnt_path, fstype = fs_type, args = opts)
        except NameError, info:
            raise Exception("mount name error: %s" % info)
        except Exception, info:
            raise Exception("mount failed: exception = %s, args = %s" %
                                             (type(info), info.args))

        # If we skipped mkfs we need to wipe the partition clean
        if skip_mkfs:
            fs.wipe()

        # Record the new file system type and options in the disk list
        disk["mounted"] = True
        disk["fs_type"] = fs_type
        disk["fs_mkfs"] = fs_makeopt
        disk["fs_opts"] = fs_mnt_opt

    # Try to wipe the file system slate clean
    utils.drop_caches()


# XXX(gps): Remove this code once refactoring is complete to get rid of these
# nasty test description strings.
def _legacy_str_to_test_flags(fs_desc_string):
    """Convert a legacy FS_LIST string into a partition.FsOptions instance."""
    match = re.search('(.*?)/(.*?)/(.*?)/(.*)$', fs_desc_string.strip())
    if not match:
        raise ValueError('unrecognized FS list entry %r' % fs_desc_string)

    flags_obj = partition.FsOptions(fstype=match.group(1).strip(),
                                    mkfs_flags=match.group(2).strip(),
                                    mount_options=match.group(3).strip(),
                                    fs_tag=match.group(4).strip())
    return flags_obj


def prepare_disks(job, fs_desc, disk1_only=False, disk_list=None):
    """
    Prepare drive(s) to contain the file system type / options given in the
    description line 'fs_desc'. When 'disk_list' is not None, we prepare all
    the drives in that list; otherwise we pick the first available data drive
    (which is usually hdc3) and prepare just that one drive.

    Args:
      fs_desc: A partition.FsOptions instance describing the test -OR- a
          legacy string describing the same in '/' separated format:
              'fstype / mkfs opts / mount opts / short name'.
      disk1_only: Boolean, defaults to False.  If True, only test the first
          disk.
      disk_list: A list of disks to prepare.  If None is given we default to
          asking get_disk_list().
    Returns:
      (mount path of the first disk, short name of the test, list of disks)
      OR (None, '', None) if no fs_desc was given.
    """

    # Special case - do nothing if caller passes no description.
    if not fs_desc:
        return (None, '', None)

    if not isinstance(fs_desc, partition.FsOptions):
        fs_desc = _legacy_str_to_test_flags(fs_desc)

    # If no disk list was given, we'll get it ourselves
    if not disk_list:
        disk_list = get_disk_list()

    # Make sure we have the appropriate 'mkfs' binary for the file system
    mkfs_bin = 'mkfs.' + fs_desc.filesystem
    if fs_desc.filesystem == 'ext4':
        mkfs_bin = 'mkfs.ext4dev'

    try:
        utils.system('which ' + mkfs_bin)
    except Exception:
        try:
            mkfs_bin = os.path.join(job.toolsdir, mkfs_bin)
            utils.system('cp -ufp %s /sbin' % mkfs_bin)
        except Exception:
            raise error.TestError('No mkfs binary available for ' +
                                  fs_desc.filesystem)

    # For 'ext4' we need to add '-E test_fs' to the mkfs options
    if fs_desc.filesystem == 'ext4':
        fs_desc.mkfs_flags += ' -E test_fs'

    # If the caller only needs one drive, grab the first one only
    if disk1_only:
        disk_list = disk_list[0:1]

    # We have all the info we need to format the drives
    mkfs_all_disks(job, disk_list, fs_desc.filesystem,
                   fs_desc.mkfs_flags, fs_desc.mount_options)

    # Return(mount path of the first disk, test tag value, disk_list)
    return (disk_list[0]['mountpt'], fs_desc.fs_tag, disk_list)


def restore_disks(job, restore=False, disk_list=None):
    """
    Restore ext2 on the drives in 'disk_list' if 'restore' is True; when
    disk_list is None, we do nothing.
    """

    if restore and disk_list is not None:
        prepare_disks(job, 'ext2 / -q -i20480 -m1 / / restore_ext2',
                           disk1_only=False,
                           disk_list=disk_list)


def wipe_disks(job, disk_list):
    """
    Wipe all of the drives in 'disk_list' using the 'wipe' functionality
    in the filesystem class.
    """
    for disk in disk_list:
        partition.wipe_filesystem(job, disk['mountpt'])


def match_fs(disk, dev_path, fs_type, fs_makeopt):
    """
    Matches the user provided fs_type and fs_makeopt with the current disk.
    """
    if disk["fs_type"] != fs_type:
        return False
    elif disk["fs_mkfs"] == fs_makeopt:
        # No need to mkfs the volume, we only need to remount it
        return True
    elif fsinfo.match_mkfs_option(fs_type, dev_path, fs_makeopt):
        if disk["fs_mkfs"] != '?':
            raise Exception("mkfs option strings differ but auto-detection"
                            " code thinks they're identical")
        else:
            return True
    else:
        return False


##############################################################################

# The following variables/methods are used to invoke fsdev in 'library' mode

FSDEV_JOB = None
FSDEV_FS_DESC = None
FSDEV_RESTORE = None
FSDEV_PREP_CNT = 0
FSDEV_DISK1_ONLY = None
FSDEV_DISKLIST = None

def use_fsdev_lib(fs_desc, disk1_only, reinit_disks):
    """
    Called from the control file to indicate that fsdev is to be used.
    """

    global FSDEV_FS_DESC
    global FSDEV_RESTORE
    global FSDEV_DISK1_ONLY
    global FSDEV_PREP_CNT

    # This is a bit tacky - we simply save the arguments in global variables
    FSDEV_FS_DESC    = fs_desc
    FSDEV_DISK1_ONLY = disk1_only
    FSDEV_RESTORE    = reinit_disks

    # We need to keep track how many times 'prepare' is called
    FSDEV_PREP_CNT   = 0


def prepare_fsdev(job):
    """
    Called from the test file to get the necessary drive(s) ready; return
    a pair of values: the absolute path to the first drive's mount point
    plus the complete disk list (which is useful for tests that need to
    use more than one drive).
    """

    global FSDEV_JOB
    global FSDEV_DISKLIST
    global FSDEV_PREP_CNT

    if not FSDEV_FS_DESC:
        return (None, None)

    # Avoid preparing the same thing more than once
    FSDEV_PREP_CNT += 1
    if FSDEV_PREP_CNT > 1:
        return (FSDEV_DISKLIST[0]['mountpt'],FSDEV_DISKLIST)

    FSDEV_JOB = job

    (path,toss,disks) = prepare_disks(job, fs_desc    = FSDEV_FS_DESC,
                                           disk1_only = FSDEV_DISK1_ONLY,
                                           disk_list  = None)
    FSDEV_DISKLIST = disks
    return (path,disks)


def finish_fsdev(force_cleanup=False):
    """
    This method can be called from the test file to optionally restore
    all the drives used by the test to a standard ext2 format. Note that
    if use_fsdev_lib() was invoked with 'reinit_disks' not set to True,
    this method does nothing. Note also that only fsdev "server-side"
    dynamic control files should ever set force_cleanup to True.
    """

    if FSDEV_PREP_CNT == 1 or force_cleanup:
        restore_disks(job       = FSDEV_JOB,
                      restore   = FSDEV_RESTORE,
                      disk_list = FSDEV_DISKLIST)


##############################################################################

class fsdev_disks:
    """
    Disk drive handling class used for file system development
    """

    def __init__(self, job):
        self.job = job


    # Some clients need to access the 'fsdev manager' instance directly
    def get_fsdev_mgr(self):
        return fd_mgr


    def config_sched_tunables(self, desc_file):

        # Parse the file that describes the scheduler tunables and their paths
        self.tune_loc = eval(open(desc_file).read())

        # Figure out what kernel we're running on
        kver = utils.system_output('uname -r')
        kver = re.match("([0-9]+\.[0-9]+\.[0-9]+).*", kver)
        kver = kver.group(1)

        # Make sure we know how to handle the kernel we're running on
        tune_files = self.tune_loc[kver]
        if tune_files is None:
            raise Exception("Scheduler tunables not available for kernel " +
                            kver)

        # Save the kernel version for later
        self.kernel_ver = kver

        # For now we always use 'anticipatory'
        tune_paths = tune_files["anticipatory"]

        # Create a dictionary out of the tunables array
        self.tune_loc = {}
        for tx in range(len(tune_paths)):
            # Grab the next tunable path from the array
            tpath = tune_paths[tx]

            # Strip any leading directory names
            tuner = tpath
            while 1:
                slash = tuner.find("/")
                if slash < 0:
                    break
                tuner = tuner[slash+1:]

            # Add mapping to the dictionary
            self.tune_loc[tuner] = tpath


    def load_sched_tunable_values(self, val_file):

        # Prepare the array of tunable values
        self.tune_list = []

        # Read the config parameters and find the values that match our kernel
        for cfgline in open(val_file):
            cfgline = cfgline.strip()
            if len(cfgline) == 0:
                continue
            if cfgline.startswith("#"):
                continue
            if cfgline.startswith("tune[") == 0:
                raise Exception("Config entry not recognized: " + cfgline)
            endKV = cfgline.find("]:")
            if endKV < 0:
                raise Exception("Config entry missing closing bracket: "
                                                                     + cfgline)
            if cfgline[5:endKV] != self.kernel_ver[0:endKV-5]:
                continue

            tune_parm = cfgline[endKV+2:].strip()
            equal = tune_parm.find("=")
            if equal < 1 or equal == len(tune_parm) - 1:
                raise Exception("Config entry doesn't have 'parameter=value' :"
                                                                     + cfgline)

            tune_name = tune_parm[:equal]
            tune_val  = tune_parm[equal+1:]

            # See if we have a matching entry in the path dictionary
            try:
                tune_path = self.tune_loc[tune_name]
            except:
                raise Exception("Unknown config entry: " + cfgline)

            self.tune_list.append((tune_name, tune_path, tune_val))


    def set_sched_tunables(self, disks):
        """
        Given a list of disks in the format returned by get_disk_list() above,
        set the I/O scheduler values on all the disks to the values loaded
        earlier by load_sched_tunables().
        """

        for dx in range(len(disks)):
            disk = disks[dx]['tunable']

            # Set the scheduler first before setting any other tunables
            self.set_tunable(disk, "scheduler",
                                   self.tune_loc["scheduler"],
                                   "anticipatory")

            # Now set all the tunable parameters we've been given
            for tune_desc in self.tune_list:
                self.set_tunable(disk, tune_desc[0],
                                       tune_desc[1],
                                       tune_desc[2])


    def set_tunable(self, disk, name, path, val):
        """
        Given a disk name, a path to a tunable value under _TUNE_PATH and the
        new value for the parameter, set the value and verify that the value
        has been successfully set.
        """

        fpath = partition.get_iosched_path(disk, path)

        # Things might go wrong so we'll catch exceptions
        try:

            step = "open tunable path"
            tunef = open(fpath, 'w', buffering=-1)

            step = "write new tunable value"
            tunef.write(val)

            step = "close the tunable path"
            tunef.close()

            step = "read back new tunable value"
            nval = open(fpath, 'r', buffering=-1).read().strip()

            # For 'scheduler' we need to fish out the bracketed value
            if name == "scheduler":
                nval = re.match(".*\[(.*)\].*", nval).group(1)

        except IOError, info:

            # Special case: for some reason 'max_sectors_kb' often doesn't work
            # with large values; try '128' if we haven't tried it already.
            if name == "max_sectors_kb" and info.errno == 22 and val != '128':
                self.set_tunable(disk, name, path, '128')
                return;

            # Something went wrong, probably a 'config' problem of some kind
            raise Exception("Unable to set tunable value '" + name +
                            "' at step '" + step + "': " + str(info))
        except Exception:

            # We should only ever see 'IOError' above, but just in case ...
            raise Exception("Unable to set tunable value for " + name)

        # Make sure the new value is what we expected
        if nval != val:
            raise Exception("Unable to correctly set tunable value for "
                            + name +": desired " + val + ", but found " + nval)

        return
