#!/usr/bin/env python
# Copyright (c) 2008-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.
#

#
# Purpose: Converts the welcometext file by converting the following keys into
#          the current values:
#              ${app.ip}
#              ${app.url}
#              ${app.name}
#              ${app.version}
#              ${vami.url}
#

from __future__ import print_function
import os, subprocess, libxml2, re, sys, socket

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


socket.setdefaulttimeout(30)


STUDIO_ROOT              = os.path.join(os.sep, 'opt', 'vmware')
VAMI_ROOT                = os.path.join(STUDIO_ROOT, "share", "vami")
INTERFACES               = os.path.join(VAMI_ROOT, "vami_interfaces")
DEFAULT_ADDRESS          = os.path.join(VAMI_ROOT, "vami_first_ip")
IPV4_ADDR                = os.path.join(VAMI_ROOT, "vami_ip_addr")
IPV6_ADDR                = os.path.join(VAMI_ROOT, "vami_ip6_addr")

APPLIANCE_TEXT_FILE      = os.path.join(STUDIO_ROOT, "etc", "isv", "welcometext")
LIGHTTPD_CONF            = os.path.join(STUDIO_ROOT, "etc", "lighttpd", "lighttpd.conf")
APPLIANCE_MANIFEST       = os.path.join(STUDIO_ROOT, "etc", "appliance-manifest.xml")
VIEW_DEPLOY              = os.path.join(STUDIO_ROOT, "share", "htdocs", "service", "core", "view-deploy.xml")

def getNameVersion ():
  sys.path.append(VAMI_ROOT)
  import vami_cim_util
  cliconn = vami_cim_util.getDefaultCIMConnection ()
  esis = cliconn.EnumerateInstances ('VAMI_ElementSoftwareIdentity')

  for esi in esis:
    ess = esi ['ElementSoftwareStatus']
    if (ess == [2, 6]):
      inst = cliconn.GetInstance (esi['Antecedent'])
      return [ inst ['Name'], inst ['VersionString'] ]


#use a re to sub inorder to be case insensitive
def replace(old, new, txt):
  pattern = re.compile(re.escape(old),re.I)
  return re.sub(pattern,new,txt,0)


def exitWithError(msg):
  print (_('ERROR: ')+msg)
  sys.exit(1)


# Interpret ${app.ip}
try:
  APP_IP=subprocess.Popen(DEFAULT_ADDRESS, stdout=subprocess.PIPE).communicate()[0].strip()

  if APP_IP == '':
    APP_IP='0.0.0.0'
except:
  APP_IP='${app.ip}'


# Interpret ${app.url}
try:
  serviceDoc=libxml2.parseFile(VIEW_DEPLOY)
  serviceXP=serviceDoc.xpathNewContext()
  APP_URL=serviceXP.xpathEval('/service/properties/property[@name="application.url"]/@value')[0].content
except:
  APP_URL='${app.url}'

# The INTERFACES program sorts the interface names
# Prepare arrays of ${vami.ipN}, ${vami.ipN.ipv4} and ${vami.ipN.ipv6}
# The array of ${vami.ipN} prefers IPv4 over IPv6
INTERFACE_IPV4S = []
INTERFACE_IPV6S = []
INTERFACE_IPS = []
try:
  devices_output=subprocess.Popen(INTERFACES, stdout=subprocess.PIPE)
  devices = devices_output.stdout
except:
  devices=[]

counter = 0

for device in devices:
  device = device.strip()

  try:
    interface_ipv4=subprocess.Popen([IPV4_ADDR, device], stdout=subprocess.PIPE).communicate()[0].strip()
  except:
    interface_ipv4=''

  try:
    interface_ipv6=subprocess.Popen([IPV6_ADDR, device], stdout=subprocess.PIPE).communicate()[0].strip()
  except:
    interface_ipv6=''

  if interface_ipv4 == '':
    interface_ipv4 = '0.0.0.0'

    if interface_ipv6 == '':
      # we continue to default to IPv4 even if there is no address at
      # all (this code really cannot be reached in practice)
      interface_ip=interface_ipv4
    else:
      interface_ip=interface_ipv6

  else:
    interface_ip=interface_ipv4

  if interface_ipv6 == '':
    interface_ipv6 = '::'

  counter = counter + 1
  INTERFACE_IPS.append(interface_ip)
  INTERFACE_IPV4S.append(interface_ipv4)
  INTERFACE_IPV6S.append(interface_ipv6)

# Interpret ${app.version} ${app.name} from sfcbd first, then fall back to files
try:
  APP_NAME, APP_VERSION = getNameVersion()
except:
  try:
    updateDoc=libxml2.parseFile(APPLIANCE_MANIFEST)
    updateXP=updateDoc.xpathNewContext()
    APP_VERSION=updateXP.xpathEval('/update/fullVersion/text()')[0].content
    APP_NAME=updateXP.xpathEval('/update/product/text()')[0].content
  except:
    APP_VERSION='${app.version}'
    APP_NAME='${app.name}'


try:
  lighttpdconf=open(LIGHTTPD_CONF, 'r')
  VAMI_PORT=''
  for line in lighttpdconf:
    kv = line.split('=')
    if kv[0].strip() == 'server.port':
      VAMI_PORT=kv[1].strip()

  lighttpdconf.close()
except:
  VAMI_PORT='${vami.port}'


try:
  fd=open(APPLIANCE_TEXT_FILE, 'r')
  welcomeTxt=fd.read()
  fd.close()
except:
  exitWithError(_('Unable to open ') + APPLIANCE_TEXT_FILE)

# if APP_IP is IPv6, add square brackets
if APP_IP.find(':') == -1:
  VAMI_URL='https://'+APP_IP+':'+VAMI_PORT+'/'
else:
  VAMI_URL='https://['+APP_IP+']:'+VAMI_PORT+'/'
  # because APP_URL is handled differently, alter APP_URL
  if APP_URL.find('${app.ip}') > -1:
    APP_URL=APP_URL.replace('${app.ip}','[' + APP_IP + ']')

# Prepare the ${vami.urlN} from the ${vami.ipN}
# Replace both in the welcomeTxt
counter = 0
for VAMI_IPx in INTERFACE_IPS:
  # if VAMI_IPx is IPv6, add square brackets
  if VAMI_IPx.find(':') == -1:
    VAMI_URLx='https://'+VAMI_IPx+':'+VAMI_PORT+'/'
  else:
    VAMI_URLx='https://['+VAMI_IPx+']:'+VAMI_PORT+'/'
  key = '${vami.ip'   + str(counter) + '}'
  welcomeTxt = replace(key, VAMI_IPx,   welcomeTxt)
  key = '${vami.url' + str(counter) + '}'
  welcomeTxt = replace(key, VAMI_URLx, welcomeTxt)
  counter = counter + 1

# Prepare the ${vami.urlN.ipv4} from the ${vami.ipN.ipv4}
# Replace both in the welcomeTxt
counter = 0
for VAMI_IPx in INTERFACE_IPV4S:
  VAMI_URLx='https://'+VAMI_IPx+':'+VAMI_PORT+'/'
  key = '${vami.ip'   + str(counter) + '.ipv4}'
  welcomeTxt = replace(key, VAMI_IPx,   welcomeTxt)
  key = '${vami.url' + str(counter) + '.ipv4}'
  welcomeTxt = replace(key, VAMI_URLx, welcomeTxt)
  counter = counter + 1

# Prepare the ${vami.urlN.ipv6} from the ${vami.ipN.ipv6}
# Replace both in the welcomeTxt
counter = 0
for VAMI_IPx in INTERFACE_IPV6S:
  VAMI_URLx='https://['+VAMI_IPx+']:'+VAMI_PORT+'/'
  key = '${vami.ip'   + str(counter) + '.ipv6}'
  welcomeTxt = replace(key, VAMI_IPx,   welcomeTxt)
  key = '${vami.url' + str(counter) + '.ipv6}'
  welcomeTxt = replace(key, VAMI_URLx, welcomeTxt)
  counter = counter + 1

#app.url is first in case it contains a recursive kv to replace
for kv in [('${app.url}',APP_URL), ('${vami.url}',VAMI_URL), ('${app.ip}',APP_IP), ('${app.name}',APP_NAME), ('${app.version}',APP_VERSION), ('${vami.port}',VAMI_PORT)]:
  welcomeTxt = replace(kv[0], kv[1], welcomeTxt)

print (welcomeTxt)
