#!/usr/bin/python
#
# Copyright 2011 VMware, Inc. All rights reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

#
# Query the appliance manifest file, and return True or False
# (exiting with the same status) based on whether the
# networking protocol given as the name of this command
# is to be exposed in the appliance.
#
from __future__ import print_function

import sys
import os
import libxml2
import getopt

import gettext
__t = gettext.translation('vami_ipsupport', '/opt/vmware/lib/locale', fallback=True)
_ = __t.ugettext if sys.version_info[0] < 3 else __t.gettext


#
# Pathnames
#
STUDIO_DIR           = os.path.join(os.sep, 'opt', 'vmware')
APPLIANCE_MANIFEST   = os.path.join(STUDIO_DIR, 'etc', 'appliance-manifest.xml')
IPV4_PGMNAME         = 'vami_ipv4support'
IPV6_PGMNAME         = 'vami_ipv6support'


#
# Namespaces in APPLIANCE_MANIFEST
#
NSDICT = \
{
    'xsi':"http://www.w3.org/2001/XMLSchema-instance",
    'vadk':"http://www.vmware.com/schema/vadk",
    'ovf':"http://schemas.dmtf.org/ovf/envelope/1",
    'vssd':"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData",
    'rasd':"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData",
    'vmw':"http://www.vmware.com/schema/ovf"
}

#
# Xpath expressions for APPLIANCE_MANIFEST
#
XPATH_ROOT           = "//update"
XPATH_NETWORK        = XPATH_ROOT + '/Network'
XPATH_PROTOCOLS      = 'protocols'

#
# Constants related to the content of APPLIANCE_MANIFEST
#
IPV4_PROTOCOL_NAME   = 'IPv4'
IPV6_PROTOCOL_NAME   = 'IPv6'



def stderr(msg):
    print(msg, file=sys.stderr)


def ipv4_enabled(protocols):
    if IPV4_PROTOCOL_NAME in protocols:
        return True
    return False


def ipv6_enabled(protocols):
    if IPV6_PROTOCOL_NAME in protocols:
        return True
    return False


def usage():
    stderr(_("Usage: ") + sys.argv[0] + " [-q|--quiet]")


def main():
    protocol_to_function_map = {
        IPV4_PGMNAME:ipv4_enabled,
        IPV6_PGMNAME:ipv6_enabled
    }
    protocols = []
    program_name = os.path.basename(sys.argv[0])
    quiet = False

    try:
        opts, args = getopt.getopt(sys.argv[1:],
                                   "qh",
                                   ["quiet", "help"])

    except getopt.GetoptError as msg:
        stderr(msg)
        usage()
        return 1

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif o in ("-q", "--quiet"):
            quiet = True

    try:
        doc = libxml2.parseFile(APPLIANCE_MANIFEST)
    except Exception as msg:
        stderr(_("Error: Unable to parse the appliance manifest file: ") +
               APPLIANCE_MANIFEST + " " + str(msg))
        return 1

    xp = doc.xpathNewContext()
    for k, v in NSDICT.items():
        xp.xpathRegisterNs(k, v)

    nodes = xp.xpathEval(XPATH_NETWORK)
    for n in nodes:
        protocols = n.prop(XPATH_PROTOCOLS).split(',')
        # remove any white space around each protocol name
        protocols = [x.strip() for x in protocols]

    if program_name not in protocol_to_function_map:
        stderr(_("Error: unknown program name: ") + program_name)
        return 1

    ret = protocol_to_function_map[program_name](protocols)
    if not quiet:
        if ret:
            print ('True')
        else:
            print ('False')
    #
    # invert return for proper exit status
    #
    return not ret


if __name__ == "__main__":
    sys.exit(main())
