"""
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 optparse
import os
import subprocess
import sys
import xml.etree.ElementTree as ET

class VersionBuilder:
  """
  Used to build a version definition file
  """
  def __init__(self, filename):
    self._check_xmllint()

    self.filename = filename

    if os.path.exists(filename):
      tree = ET.ElementTree()
      tree.parse(filename)
      root = tree.getroot()
    else:
      attribs = {}
      attribs['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance"
      attribs['xsi:noNamespaceSchemaLocation'] = "version_definition.xsd"
      root = ET.Element("repository-version", attribs)

      ET.SubElement(root, "release")
      ET.SubElement(root, "manifest")
      ET.SubElement(root, "available-services")
      ET.SubElement(root, "repository-info")

    self.root_element = root


  def persist(self):
    """
    Saves the XML file
    """
    p = subprocess.Popen(['xmllint', '--format', '--output', self.filename, '-'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
    (stdout, stderr) = p.communicate(input=ET.tostring(self.root_element))

  def finalize(self, xsd_file):
    """
    Validates the XML file against the XSD
    """
    args = ['xmllint', '--noout', '--load-trace', '--schema', xsd_file, self.filename]

    p = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
    (stdout, stderr) = p.communicate()

    if p.returncode != 0:
      raise Exception(stderr)

    if len(stdout) > 0:
      print(stdout.decode("UTF-8"))

    if len(stderr) > 0:
      print(stderr.decode("UTF-8"))

  def set_release(self, type=None, stack=None, version=None, build=None, notes=None, display=None,
    compatible=None):
    """
    Create elements of the 'release' parent
    """
    release_element = self.root_element.find("./release")

    if release_element is None:
      raise Exception("Element 'release' is not found")

    if type:
      update_simple(release_element, "type", type)

    if stack:
      update_simple(release_element, "stack-id", stack)

    if version:
      update_simple(release_element, "version", version)

    if build:
      update_simple(release_element, "build", build)

    if compatible:
      update_simple(release_element, "compatible-with", compatible)

    if notes:
      update_simple(release_element, "release-notes", notes)

    if display:
      update_simple(release_element, "display", display)

  def set_os(self, os_family, package_version=None):
    repo_parent = self.root_element.find("./repository-info")
    if repo_parent is None:
      raise Exception("'repository-info' element is not found")

    os_element = self.findByAttributeValue(repo_parent, "./os", "family", os_family)
    if os_element is None:
      os_element = ET.SubElement(repo_parent, 'os')
      os_element.set('family', os_family)

    if package_version:
      pv_element = os_element.find("package-version")
      if pv_element is None:
        pv_element = ET.SubElement(os_element, "package-version")
      pv_element.text = package_version


  def add_manifest(self, id, service_name, version, version_id = None):
    """
    Add a manifest service.  A manifest lists all services in a repo, whether they are to be
    upgraded or not.
    """
    manifest_element = self.root_element.find("./manifest")

    if manifest_element is None:
      raise Exception("Element 'manifest' is not found")

    service_element = self.findByAttributeValue(manifest_element, "./service", "id", id)

    if service_element is None:
      service_element = ET.SubElement(manifest_element, "service")
      service_element.set('id', id)

    service_element.set('name', service_name)
    service_element.set('version', version)
    if version_id:
      service_element.set('version-id', version_id)

  def add_available(self, manifest_id, available_components=None):
    """
    Adds services available to upgrade for patches
    """
    manifest_element = self.root_element.find("./manifest")
    if manifest_element is None:
      raise Exception("'manifest' element is not found")

    service_element = self.findByAttributeValue(manifest_element, "./service", "id", manifest_id)
    if service_element is None:
      raise Exception("Cannot add an available service for {0}; it's not on the manifest".format(manifest_id))

    available_element = self.root_element.find("./available-services")
    if available_element is None:
      raise Exception("'available-services' is not found")

    service_element = self.findByAttributeValue(available_element, "./service", "idref", manifest_id)

    if service_element is not None:
      available_element.remove(service_element)

    service_element = ET.SubElement(available_element, "service")
    service_element.set('idref', manifest_id)

    if available_components:
      components = available_components.split(',')
      for component in components:
        e = ET.SubElement(service_element, 'component')
        e.text = component

  def add_repo(self, os_family, repo_id, repo_name, base_url):
    """
    Adds a repository
    """
    repo_parent = self.root_element.find("./repository-info")
    if repo_parent is None:
      raise Exception("'repository-info' element is not found")

    os_element = self.findByAttributeValue(repo_parent, "./os", "family", os_family)
    if os_element is None:
      os_element = ET.SubElement(repo_parent, 'os')
      os_element.set('family', os_family)

    if self.useNewSyntax():
      repo_element = os_element.find("./repo/[reponame='{0}']".format(repo_name))
    else:
      repo_element = self.findByValue(os_element, "./repo/reponame", repo_name)

    if repo_element is not None:
      os_element.remove(repo_element)

    repo_element = ET.SubElement(os_element, 'repo')
    e = ET.SubElement(repo_element, 'baseurl')
    e.text = base_url

    e = ET.SubElement(repo_element, 'repoid')
    e.text = repo_id

    e = ET.SubElement(repo_element, 'reponame')
    e.text = repo_name


  def _check_xmllint(self):
    """
    Verifies utility xmllint is available
    """
    try:
      p = subprocess.Popen(['xmllint', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
      (stdout, stderr) = p.communicate()

      if p.returncode != 0:
        raise Exception("xmllint command does not appear to be available")

    except:
      raise Exception("xmllint command does not appear to be available")

  def findByAttributeValue(self, root, element, attribute, value):
    if self.useNewSyntax():
      return root.find("./{0}[@{1}='{2}']".format(element, attribute, value))
    else:
      for node in root.findall("{0}".format(element)):
        if node.attrib[attribute] == value:
          return node
      return None;
  
  def findByValue(self, root, element, value):
    for node in root.findall("{0}".format(element)):
      if node.text == value:
        return node
    return None

  def useNewSyntax(self):
     #Python2.7 and newer shipps with ElementTree that supports a different syntax for XPath queries
     major=sys.version_info[0]
     minor=sys.version_info[1]
     if major > 3 :
       return True
     elif major == 2:
       return (minor > 6)
     else:
       return False;

def update_simple(parent, name, value):
  """
  Helper method to either update or create the element
  """
  element = parent.find('./' + name) 

  if element is None:
    element = ET.SubElement(parent, name)
    element.text = value
  else:
    element.text = value

def process_release(vb, options):
  """
  Create elements of the 'release' parent
  """
  if options.release_type:
    vb.set_release(type=options.release_type)

  if options.release_stack:
    vb.set_release(stack=options.release_stack)

  if options.release_version:
    vb.set_release(version=options.release_version)

  if options.release_build:
    vb.set_release(build=options.release_build)

  if options.release_compatible:
    vb.set_release(compatible=options.release_compatible)

  if options.release_notes:
    vb.set_release(notes=options.release_notes)

  if options.release_display:
    vb.set_release(display=options.release_display)

  if options.release_package_version:
    vb.set_release(package_version=options.release_package_version)

def process_manifest(vb, options):
  """
  Creates the manifest element
  """
  if not options.manifest:
    return

  vb.add_manifest(options.manifest_id, options.manifest_service, options.manifest_version, options.manifest_version_id)

def process_available(vb, options):
  """
  Processes available service elements
  """
  if not options.available:
    return

  vb.add_available(options.manifest_id, options.available_components)


def process_os(vb, options):
  if not options.os:
    return

  vb.set_os(options.os_family, options.os_package_version)

def process_repo(vb, options):
  """
  Processes repository options.  This method doesn't update or create individual elements, it
  creates the entire repo structure
  """
  if not options.repo:
    return

  vb.add_repo(options.repo_os, options.repo_id, options.repo_name, options.repo_url)

def validate_manifest(parser, options):
  """
  Validates manifest options from the command line
  """
  if not options.manifest:
    return

  template = "When specifying --manifest, {0} is also required"

  if not options.manifest_id:
    parser.error(template.format("--manifest-id"))
  
  if not options.manifest_service:
    parser.error(template.format("--manifest-service"))

  if not options.manifest_version:
    parser.error(template.format("--manifest-version"))

def validate_available(parser, options):
  """
  Validates available service options from the command line
  """
  if not options.available:
    return

  if not options.manifest_id:
    parser.error("When specifying --available, --manifest-id is also required")

def validate_os(parser, options):
  if not options.os:
    return

  if not options.os_family:
    parser.error("When specifying --os, --os-family is also required")

def validate_repo(parser, options):
  """
  Validates repo options from the command line
  """
  if not options.repo:
    return

  template = "When specifying --repo, {0} is also required"

  if not options.repo_os:
    parser.error(template.format("--repo-os"))

  if not options.repo_url:
    parser.error(template.format("--repo-url"))

  if not options.repo_id:
    parser.error(template.format("--repo-id"))

  if not options.repo_name:
    parser.error(template.format("--repo-name"))


def main(argv):
  parser = optparse.OptionParser(
    epilog="OS utility 'xmllint' is required for this tool to function.  It handles pretty-printing and XSD validation.")
  
  parser.add_option('--file', dest='filename',
    help="The output XML file")

  parser.add_option('--finalize', action='store_true', dest='finalize',
    help="Finalize and validate the XML file")
  parser.add_option('--xsd', dest='xsd_file',
    help="The XSD location when finalizing")

  parser.add_option('--release-type', type='choice', choices=['STANDARD', 'PATCH'], dest='release_type' ,
    help="Indicate the release type: i.e. STANDARD or PATCH")
  parser.add_option('--release-stack', dest='release_stack',
    help="The stack id: e.g. HDP-2.4")
  parser.add_option('--release-version', dest='release_version',
    help="The release version without build number: e.g. 2.4.0.1")
  parser.add_option('--release-build', dest='release_build',
    help="The release build number: e.g. 1234")
  parser.add_option('--release-compatible', dest='release_compatible',
    help="Regular Expression string to identify version compatibility for patches: e.g. 2.4.1.[0-9]")
  parser.add_option('--release-notes', dest='release_notes',
    help="A http link to the documentation notes")
  parser.add_option('--release-display', dest='release_display',
    help="The display name for this release")
  parser.add_option('--release-package-version', dest='release_package_version',
    help="Identifier to use when installing packages, generally a part of the package name")

  parser.add_option('--manifest', action='store_true', dest='manifest',
    help="Add a manifest service with other options: --manifest-id, --manifest-service, --manifest-version, --manifest-version-id")
  parser.add_option('--manifest-id', dest='manifest_id',
    help="Unique ID for a service in a manifest.  Required when specifying --manifest and --available")
  parser.add_option('--manifest-service', dest='manifest_service')
  parser.add_option('--manifest-version', dest='manifest_version')
  parser.add_option('--manifest-version-id', dest='manifest_version_id')

  parser.add_option('--available', action='store_true', dest='available',
    help="Add an available service with other options: --manifest-id, --available-components")
  parser.add_option('--available-components', dest='available_components',
    help="A CSV of service components that are intended to be upgraded via patch. \
      Omitting this implies the entire service should be upgraded")

  parser.add_option('--os', action='store_true', dest='os', help="Add OS data with options --os-family, --os-package-version")
  parser.add_option('--os-family', dest='os_family', help="The operating system: i.e redhat7, debian7, ubuntu12, ubuntu14, suse11, suse12")
  parser.add_option('--os-package-version', dest='os_package_version',
    help="The package version to use for the OS")

  parser.add_option('--repo', action='store_true', dest='repo',
    help="Add repository data with options: --repo-os, --repo-url, --repo-id, --repo-name")
  parser.add_option('--repo-os', dest='repo_os',
    help="The operating system type: i.e. redhat6, redhat7, debian7, ubuntu12, ubuntu14, ubuntu16, suse11, suse12")
  parser.add_option('--repo-url', dest='repo_url',
    help="The base url for the repository data")
  parser.add_option('--repo-id', dest='repo_id', help="The ID of the repo")
  parser.add_option('--repo-name', dest='repo_name', help="The name of the repo")

  (options, args) = parser.parse_args()

  # validate_filename
  if not options.filename:
    parser.error("--file option is required")

  # validate_finalize
  if options.finalize and not options.xsd_file:
    parser.error("Must supply XSD (--xsd) when finalizing")

  validate_manifest(parser, options)
  validate_available(parser, options)
  validate_os(parser, options)
  validate_repo(parser, options)

  vb = VersionBuilder(options.filename)

  process_release(vb, options)
  process_manifest(vb, options)
  process_available(vb, options)
  process_os(vb, options)
  process_repo(vb, options)

  # save file
  vb.persist()

  if options.finalize:
    vb.finalize(options.xsd_file)

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