
from __future__ import absolute_import

from vdsm import utils
import vdsm.common.supervdsm as svdsm
from vdsm.storage import fileVolume
from vdsm.storage.sdc import sdCache

try:
    from vdsm.gluster.exception import GlusterException
    _glusterEnabled = True
except ImportError:
    _glusterEnabled = False

VOLUME_TRANS_MAP = {
    'TCP': 'tcp',
    'RDMA': 'rdma'
}


class GlusterVolume(fileVolume.FileVolume):

    def __init__(self, repoPath, sdUUID, imgUUID, volUUID):
        fileVolume.FileVolume.__init__(self, repoPath, sdUUID, imgUUID,
                                       volUUID)

    def getVmVolumeInfo(self):
        rpath = sdCache.produce(self.sdUUID).getRealPath()
        volfileServer, volname = rpath.rsplit(":", 1)
        volname = volname.strip('/')

        svdsmProxy = svdsm.getProxy()

        try:
            res = svdsmProxy.glusterVolumeInfo(volname, volfileServer)
        except GlusterException:
            self.log.warning("Unable to find transport type for GlusterFS"
                             " volume %s. GlusterFS server = %s."
                             "Defaulting to tcp",
                             volname, volfileServer, exc_info=True)
            transport = VOLUME_TRANS_MAP['TCP']
            brickServers = []
        else:
            vol_info = res[volname]
            transport = VOLUME_TRANS_MAP[vol_info['transportType'][0]]
            brickServers = utils.unique(
                brick.split(":", 1)[0]
                for brick in vol_info['bricks']
            )
            if volfileServer in brickServers:
                brickServers.remove(volfileServer)

        volPort = "0"

        imgFilePath = self.getVolumePath()
        imgFilePath_list = imgFilePath.rsplit("/")

        imgFileRelPath = "/".join(imgFilePath_list[-4:])

        glusterPath = volname + '/' + imgFileRelPath

        hosts = [dict(name=volfileServer,
                      port=volPort,
                      transport=transport)]
        hosts.extend(dict(name=brickServer, port=volPort, transport=transport)
                     for brickServer in brickServers)

        return {
            'type': 'network',
            'path': glusterPath,
            'protocol': 'gluster',
            'hosts': hosts,
        }
