
from __future__ import absolute_import
from __future__ import division

import logging
import os
import stat
import uuid

from vdsm.constants import P_LIBVIRT_VMCHANNELS, P_OVIRT_VMCONSOLES
from vdsm.storage.fileUtils import resolveGid
from vdsm.common.fileutils import parse_key_val_file

from . import expose


@expose
def prepareVmChannel(socketFile, group=None):
    if (socketFile.startswith(P_LIBVIRT_VMCHANNELS) or
       socketFile.startswith(P_OVIRT_VMCONSOLES)):
        fsinfo = os.stat(socketFile)
        mode = fsinfo.st_mode | stat.S_IWGRP
        os.chmod(socketFile, mode)
        if group is not None:
            os.chown(socketFile,
                     fsinfo.st_uid,
                     resolveGid(group))
    else:
        raise Exception("Incorporate socketFile")


@expose
def hugepages_alloc(count, path):
    existing_pages = 0
    allocated_pages = 0

    with open(path, 'r') as f:
        existing_pages = int(f.read())

    count = max(-existing_pages, count)

    with open(path, 'w') as f:
        f.write(str(existing_pages + count))

    with open(path, 'r') as f:
        allocated_pages = int(f.read()) - existing_pages

    return allocated_pages


@expose
def mdev_create(device, mdev_type, mdev_uuid=None):
    path = os.path.join(
        '/sys/class/mdev_bus/{}/mdev_supported_types/{}/create'.format(
            device, mdev_type
        )
    )

    if mdev_uuid is None:
        mdev_uuid = str(uuid.uuid4())

    with open(path, 'w') as f:
        f.write(mdev_uuid)

    return mdev_uuid


@expose
def mdev_delete(device, mdev_uuid):
    path = os.path.join(
        '/sys/class/mdev_bus/{}/{}/remove'.format(
            device, mdev_uuid
        )
    )

    with open(path, 'w') as f:
        f.write('1')


QEMU_CONFIG_FILE = '/etc/libvirt/qemu.conf'


@expose
def check_qemu_conf_contains(key, value):
    try:
        kvs = parse_key_val_file(QEMU_CONFIG_FILE)
        return kvs.get(key, '0') == value
    except:
        logging.error('Could not check %s for %s', QEMU_CONFIG_FILE, key)
        raise
