
from __future__ import absolute_import
from __future__ import division
import os
import selinux
import shutil
import sys
import tempfile
import time

from . import YES, NO
from vdsm.tool import service
from vdsm.common import cmdutils
from vdsm.common import commands
from vdsm import constants


_CONF_FILE = "/etc/multipath.conf"



_OLD_TAGS = (
)



_NO_PATH_RETRY = 4

_CONF_DATA = """\
%(current_tag)s


defaults {


    polling_interval            5


    no_path_retry               %(no_path_retry)d


    user_friendly_names         no


    flush_on_last_del           yes


    fast_io_fail_tmo            5


    dev_loss_tmo                30


    max_fds                     4096
}


blacklist {
        protocol "(scsi:adt|scsi:sbp)"
}

devices {
    device {
        all_devs                yes
        no_path_retry           %(no_path_retry)d
    }
}


""" % {"current_tag": _CURRENT_TAG,
       "no_path_retry": _NO_PATH_RETRY}

services = []


def configure():
    if os.path.exists(_CONF_FILE):
        backup = _CONF_FILE + '.' + time.strftime("%Y%m%d%H%M")
        shutil.copyfile(_CONF_FILE, backup)
        sys.stdout.write("Backup previous multipath.conf to %r\n" % backup)

    with tempfile.NamedTemporaryFile(
            mode="wb",
            prefix=os.path.basename(_CONF_FILE) + ".tmp",
            dir=os.path.dirname(_CONF_FILE),
            delete=False) as f:
        try:
            f.write(_CONF_DATA)
            f.flush()
            selinux.restorecon(f.name)
            os.chmod(f.name, 0o644)
            os.rename(f.name, _CONF_FILE)
        except:
            os.unlink(f.name)
            raise

    try:
        commands.run([constants.EXT_MULTIPATH, "-F"])
    except cmdutils.Error:
        pass

    try:
        service.service_reload("multipathd")
    except service.ServiceOperationError:
        status = service.service_status("multipathd", False)
        if status == 0:
            raise


def isconfigured():
    if os.path.exists(_CONF_FILE):
        first = second = ''
        with open(_CONF_FILE) as f:
            mpathconf = [x.strip("\n") for x in f.readlines()]
        try:
            first = mpathconf[0]
            second = mpathconf[1]
        except IndexError:
            pass
        if _PRIVATE_TAG in second or _OLD_PRIVATE_TAG in second:
            sys.stdout.write("Manual override for multipath.conf detected"
                             " - preserving current configuration\n")
            if _CURRENT_TAG not in first:
                sys.stdout.write("This manual override for multipath.conf "
                                 "was based on downrevved template. "
                                 "You are strongly advised to "
                                 "contact your support representatives\n")
            return YES

        if _CURRENT_TAG in first:
            sys.stdout.write("Current revision of multipath.conf detected,"
                             " preserving\n")
            return YES

        for tag in _OLD_TAGS:
            if tag in first:
                sys.stdout.write("Downrev multipath.conf detected, "
                                 "upgrade required\n")
                return NO

    sys.stdout.write("multipath requires configuration\n")
    return NO
