#!/usr/bin/python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import logging
import re
import sys
import os
import subprocess
from threading import Timer
from xml.dom.minidom import parse
from cloudutils.configFileOps import configFileOps
from cloudutils.networkConfig import networkConfig

logging.basicConfig(filename='/var/log/libvirt/qemu-hook.log',
                    filemode='a',
                    format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                    datefmt='%H:%M:%S',
                    level=logging.INFO)
logger = logging.getLogger('qemu-hook')

customDir = "/etc/libvirt/hooks/custom"
customDirPermissions = 0o744
timeoutSeconds = 10 * 60
validQemuActions = ['prepare', 'start', 'started', 'stopped', 'release', 'migrate', 'restore', 'reconnect', 'attach']

def isOldStyleBridge(brName):
    if brName.find("cloudVirBr") == 0:
        return True
    else:
        return False

def isNewStyleBridge(brName):
    if brName.startswith('brvx-'):
        return False
    if re.match(r"br(\w+)-(\d+)", brName) == None:
        return False
    else:
        return True

def getGuestNetworkDevice():
    netlib = networkConfig()
    cfo = configFileOps("/etc/cloudstack/agent/agent.properties")
    guestDev = cfo.getEntry("guest.network.device")
    enslavedDev = netlib.getEnslavedDev(guestDev, 1)
    return enslavedDev.split(".")[0]

def handleMigrateBegin():
    try:
        domain = parse(sys.stdin)
        for interface in domain.getElementsByTagName("interface"):
            source = interface.getElementsByTagName("source")[0]
            bridge = source.getAttribute("bridge")
            if isOldStyleBridge(bridge):
                vlanId = bridge.replace("cloudVirBr", "")
                phyDev = getGuestNetworkDevice()
            elif isNewStyleBridge(bridge):
                vlanId = re.sub(r"br(\w+)-", "", bridge)
                phyDev = re.sub(r"-(\d+)$", "" , re.sub(r"^br", "" ,bridge))
                netlib = networkConfig()
                if not netlib.isNetworkDev(phyDev):
                    phyDev = getGuestNetworkDevice()
            else:
                continue
            newBrName = "br" + phyDev + "-" + vlanId
            source.setAttribute("bridge", newBrName)
        print(domain.toxml())
    except:
        pass


def executeCustomScripts(sysArgs):
    if not os.path.exists(customDir) or not os.path.isdir(customDir):
        return

    scripts = getCustomScriptsFromDirectory()

    for scriptName in scripts:
        executeScript(scriptName, sysArgs)


def executeScript(scriptName, sysArgs):
    logger.info('Executing custom script: %s, parameters: %s' % (scriptName, ' '.join(map(str, sysArgs))))
    path = customDir + os.path.sep + scriptName

    if not os.access(path, os.X_OK):
        logger.warning('Custom script: %s is not executable; skipping execution.' % scriptName)
        return

    try:
        process = subprocess.Popen([path] + sysArgs, stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE, shell=False)
        try:
            timer = Timer(timeoutSeconds, terminateProcess, [process, scriptName])
            timer.start()
            output, error = process.communicate()

            if process.returncode == -15:
                logger.error('Custom script: %s terminated after timeout of %s second[s].'
                             % (scriptName, timeoutSeconds))
                return
            if process.returncode != 0:
                logger.info('return code: %s' % str(process.returncode))
                raise Exception(error)
            logger.info('Custom script: %s finished successfully; output: \n%s' %
                        (scriptName, str(output)))
        finally:
            timer.cancel()
    except (OSError, Exception) as e:
        logger.exception("Custom script: %s finished with error: \n%s" % (scriptName, e))


def terminateProcess(process, scriptName):
    logger.warning('Custom script: %s taking longer than %s second[s]; terminating..' % (scriptName, str(timeoutSeconds)))
    process.terminate()


def getCustomScriptsFromDirectory():
    return sorted([fileName for fileName in os.listdir(customDir) if (fileName is not None) & (fileName != "") & ('_' in fileName) &
                                          (fileName.startswith((action + '_')) | fileName.startswith(('all' + '_')))], key=lambda fileName: substringAfter(fileName, '_'))


def substringAfter(s, delimiter):
    return s.partition(delimiter)[2]


if __name__ == '__main__':
    if len(sys.argv) != 5:
        sys.exit(0)

    # For docs refer https://libvirt.org/hooks.html#qemu
    logger.debug("Executing qemu hook with args: %s" % sys.argv)
    action, status = sys.argv[2:4]

    if action not in validQemuActions:
        logger.error('The given action: %s, is not a valid libvirt qemu operation.' % action)
        sys.exit(0)

    if action == "migrate" and status == "begin":
        handleMigrateBegin()

    executeCustomScripts(sys.argv[1:])
