#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed 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.
#
"""Directly processes text of appengine-web.xml.

AppEngineWebXmlParser is called with XML string to produce an AppEngineWebXml
object containing the data from that string.

AppEngineWebXmlParser: converts xml to AppEngineWebXml object
AppEngineWebXml: Contains relevant information from app_engine_web.xml

Dummy Classes:
ManualScaling
BasicScaling
UserPermission
AdminConsolePage
ErrorHandler
ApiConfig
PrioritySpecifierEntry
StaticFileInclude
AppEngineConfigException - generically reports illegal inputs.

"""

import os
import re
from xml.etree import ElementTree

from google.appengine.tools import xml_parser_utils
from google.appengine.tools.app_engine_config_exception import AppEngineConfigException
from google.appengine.tools.value_mixin import ValueMixin


class AppEngineWebXmlParser(object):
  """Provides logic for walking down XML tree and pulling data."""

  def ProcessXml(self, xml_str):
    """Parses XML string and returns object representation of relevant info.

    Uses ElementTree parser to return a tree representation of XML.
    Then walks down that tree and extracts important info and adds it
    to the object.

    Args:
      xml_str: The XML string itself

    Returns:
      If there is well-formed but illegal XML, returns a list of
      errors. Otherwise, returns an AppEngineWebXml object containing
      information from XML.

    Raises:
      AppEngineConfigException: In case of malformed XML or illegal inputs.
    """
    try:
      self.app_engine_web_xml = AppEngineWebXml()
      self.errors = []
      xml_root = ElementTree.fromstring(xml_str)

      for child in xml_root.getchildren():
        self.ProcessChildNode(child)
      self.CheckScalingConstraints()
      if self.errors:

        raise AppEngineConfigException('\n'.join(self.errors))
      return self.app_engine_web_xml
    except ElementTree.ParseError:
      raise AppEngineConfigException('Bad input -- not valid XML')

  def ProcessChildNode(self, child_node):
    """Processes second-level nodes one by one.

    According to the tag of the node passed in, processes it a certain way.

    Args:
      child_node: a "second-level" node in the appengine-web.xml tree

    Raises:
      AppEngineConfigException - in case tag is not recognized.
    """

    element_name = xml_parser_utils.GetTag(child_node)
    camel_case_name = ''.join(part.title() for part in element_name.split('-'))
    method_name = 'Process%sNode' % camel_case_name
    if hasattr(self, method_name) and method_name is not 'ProcessChildNode':
      getattr(self, method_name)(child_node)
    else:
      self.errors.append('Second-level tag not recognized: <%s>' % element_name)

  def ProcessSystemPropertiesNode(self, node):
    for sub_node in xml_parser_utils.GetNodes(node, 'property'):
      prop_name = xml_parser_utils.GetAttribute(sub_node, 'name')
      prop_value = xml_parser_utils.GetAttribute(sub_node, 'value')
      self.app_engine_web_xml.system_properties[prop_name] = prop_value

  def ProcessVmSettingsNode(self, node):
    for sub_node in xml_parser_utils.GetNodes(node, 'setting'):
      prop_name = xml_parser_utils.GetAttribute(sub_node, 'name')
      prop_value = xml_parser_utils.GetAttribute(sub_node, 'value')
      self.app_engine_web_xml.vm_settings[prop_name] = prop_value

  def ProcessEnvVariablesNode(self, node):
    for sub_node in xml_parser_utils.GetNodes(node, 'env-var'):
      prop_name = xml_parser_utils.GetAttribute(sub_node, 'name')
      prop_value = xml_parser_utils.GetAttribute(sub_node, 'value')
      self.app_engine_web_xml.env_variables[prop_name] = prop_value

  def ProcessApplicationNode(self, node):
    self.app_engine_web_xml.app_id = node.text

  def ProcessVersionNode(self, node):
    self.app_engine_web_xml.version_id = node.text

  def ProcessSourceLanguageNode(self, node):
    self.app_engine_web_xml.source_language = node.text

  def ProcessModuleNode(self, node):
    self.app_engine_web_xml.module = node.text

  def ProcessInstanceClassNode(self, node):
    self.app_engine_web_xml.instance_class = node.text

  def ProcessAutomaticScalingNode(self, node):
    """Sets automatic scaling settings."""
    automatic_scaling = AutomaticScaling()
    automatic_scaling.min_pending_latency = xml_parser_utils.GetChildNodeText(
        node, 'min-pending-latency').strip()
    automatic_scaling.max_pending_latency = xml_parser_utils.GetChildNodeText(
        node, 'max-pending-latency').strip()
    automatic_scaling.min_idle_instances = xml_parser_utils.GetChildNodeText(
        node, 'min-idle-instances').strip()
    automatic_scaling.max_idle_instances = xml_parser_utils.GetChildNodeText(
        node, 'max-idle-instances').strip()
    self.app_engine_web_xml.automatic_scaling = automatic_scaling

  def ProcessManualScalingNode(self, node):
    manual_scaling = ManualScaling()
    manual_scaling.instances = xml_parser_utils.GetChildNodeText(
        node, 'instances').strip()
    self.app_engine_web_xml.manual_scaling = manual_scaling

  def ProcessBasicScalingNode(self, node):
    basic_scaling = BasicScaling()
    basic_scaling.max_instances = xml_parser_utils.GetChildNodeText(
        node, 'max-instances').strip()
    basic_scaling.idle_timeout = xml_parser_utils.GetChildNodeText(
        node, 'idle-timeout').strip()
    self.app_engine_web_xml.basic_scaling = basic_scaling

  def ProcessStaticFilesNode(self, node):
    """Processes files according to filetype."""
    for sub_node in xml_parser_utils.GetNodes(node, 'include'):
      path = xml_parser_utils.GetAttribute(sub_node, 'path').strip()
      expiration = xml_parser_utils.GetAttribute(sub_node, 'expiration').strip()
      static_file_include = StaticFileInclude()
      static_file_include.pattern = path
      static_file_include.expiration = expiration
      static_file_include.http_headers = {}

      for http_header_node in xml_parser_utils.GetNodes(
          sub_node, 'http-header'):
        name = xml_parser_utils.GetAttribute(http_header_node, 'name')
        value = xml_parser_utils.GetAttribute(http_header_node, 'value')

        if name in static_file_include.http_headers:
          self.errors.append('Headers can only be entered once; %s entered '
                             'more than once' % name)
        static_file_include.http_headers[name] = value
      self.app_engine_web_xml.static_file_includes.append(static_file_include)

    for sub_node in xml_parser_utils.GetNodes(node, 'exclude'):
      path = xml_parser_utils.GetAttribute(sub_node, 'path').strip()
      self.app_engine_web_xml.static_file_excludes.append(path)

  def ProcessResourceFilesNode(self, node):
    for sub_node in xml_parser_utils.GetNodes(node, 'include'):
      path = xml_parser_utils.GetAttribute(sub_node, 'path').strip()
      self.app_engine_web_xml.resource_file_includes.append(path)

    for sub_node in xml_parser_utils.GetNodes(node, 'exclude'):
      path = xml_parser_utils.GetAttribute(sub_node, 'path').strip()
      self.app_engine_web_xml.resource_file_excludes.append(path)

  def ProcessSslEnabledNode(self, node):
    value = xml_parser_utils.BooleanValue(node.text)
    self.app_engine_web_xml.ssl_enabled = value

  def ProcessSessionsEnabledNode(self, node):
    value = xml_parser_utils.BooleanValue(node.text)
    self.app_engine_web_xml.sessions_enabled = value

  def ProcessAsyncSessionPersistenceNode(self, node):
    enabled = xml_parser_utils.BooleanValue(
        xml_parser_utils.GetAttribute(node, 'enabled'))
    self.app_engine_web_xml.async_session_persistence = enabled
    queue_name = xml_parser_utils.GetAttribute(node, 'queue-name').strip()
    self.app_engine_web_xml.async_session_persistence_queue_name = queue_name

  def ProcessUserPermissionsNode(self, node):
    for node in xml_parser_utils.GetNodes(node, 'permission'):
      class_name = xml_parser_utils.GetAttribute(node, 'class-name').strip()
      name = xml_parser_utils.GetAttribute(node, 'name').strip()
      actions = xml_parser_utils.GetAttribute(node, 'actions').strip()
      if class_name.startswith('java.'):
        self.errors.append('Cannot specify user-permission for '
                           'classes in java.* packages.')
      user_permission = UserPermission()
      user_permission.class_name = class_name
      user_permission.name = name
      user_permission.actions = actions
      self.app_engine_web_xml.user_permissions.append(user_permission)

  def ProcessPublicRootNode(self, node):
    """Sets public root node so that it is of form "/foo"."""
    new_root = node.text
    if new_root:
      if '*' in new_root:
        self.errors.append('public-root cannot contain wildcards')
        return
      if new_root.endswith('/'):
        new_root = new_root[:-1]
      if not new_root.startswith('/'):
        new_root = '/' + new_root

      self.app_engine_web_xml.public_root = new_root

  def ProcessInboundServicesNode(self, node):
    for node in xml_parser_utils.GetNodes(node, 'service'):
      self.app_engine_web_xml.inbound_services.add(node.text)

  def ProcessPrecompilationEnabledNode(self, node):
    value = xml_parser_utils.BooleanValue(node.text)
    self.app_engine_web_xml.precompilation_enabled = value

  def ProcessAdminConsoleNode(self, node):
    for node in xml_parser_utils.GetNodes(node, 'page'):
      name = xml_parser_utils.GetAttribute(node, 'name').strip()
      url = xml_parser_utils.GetAttribute(node, 'url').strip()
      admin_console_page = AdminConsolePage()
      admin_console_page.name = name
      admin_console_page.url = url
      self.app_engine_web_xml.admin_console_pages.append(admin_console_page)

  def ProcessStaticErrorHandlersNode(self, node):
    for node in xml_parser_utils.GetNodes(node, 'handler'):
      filename = xml_parser_utils.GetAttribute(node, 'file').strip()
      error_code = xml_parser_utils.GetAttribute(node, 'error-code').strip()
      error_handler = ErrorHandler()
      error_handler.name = filename
      error_handler.code = error_code
      self.app_engine_web_xml.static_error_handlers.append(error_handler)

  def ProcessWarmupRequestsEnabledNode(self, node):
    warmup_requests_enabled = xml_parser_utils.BooleanValue(node.text)
    warmup_service = AppEngineWebXml.WARMUP_SERVICE
    if warmup_requests_enabled:
      self.app_engine_web_xml.inbound_services.add(warmup_service)
    else:
      self.app_engine_web_xml.inbound_services.remove(warmup_service)

  def ProcessThreadsafeNode(self, node):
    value = xml_parser_utils.BooleanValue(node.text)
    self.app_engine_web_xml.threadsafe = value
    self.app_engine_web_xml.threadsafe_value_provided = True

  def ProcessCodeLockNode(self, node):
    self.app_engine_web_xml.codelock = xml_parser_utils.BooleanValue(node.text)

  def ProcessVmNode(self, node):
    self.app_engine_web_xml.vm = xml_parser_utils.BooleanValue(node.text)

  def ProcessApiConfigNode(self, node):
    servlet = xml_parser_utils.GetAttribute(node, 'servlet-class').strip()
    url = xml_parser_utils.GetAttribute(node, 'url-pattern').strip()
    api_config = ApiConfig()
    api_config.servlet_class = servlet
    api_config.url = url
    self.app_engine_web_xml.api_config = api_config
    for sub_node in xml_parser_utils.GetNodes(
        node, 'endpoint-servlet-mapping-id'):
      api_id = sub_node.text.strip()
      if api_id:
        self.app_engine_web_xml.api_endpoint_ids.append(api_id)

  def ProcessPagespeedNode(self, node):
    """Processes URLs and puts them into the Pagespeed object."""
    pagespeed = Pagespeed()
    pagespeed.url_blacklist = [
        sub_node.text for sub_node in xml_parser_utils.GetNodes(
            node, 'url-blacklist')]
    pagespeed.domains_to_rewrite = [
        sub_node.text for sub_node in xml_parser_utils.GetNodes(
            node, 'domain-to-rewrite')]
    pagespeed.enabled_rewriters = [
        sub_node.text for sub_node in xml_parser_utils.GetNodes(
            node, 'enabled-rewriter')]
    pagespeed.disabled_rewriters = [
        sub_node.text for sub_node in xml_parser_utils.GetNodes(
            node, 'disabled-rewriter')]
    self.app_engine_web_xml.pagespeed = pagespeed

  def ProcessClassLoaderConfig(self, node):
    for node in xml_parser_utils.GetNodes(node, 'priority-specifier'):
      entry = PrioritySpecifierEntry()
      entry.filename = xml_parser_utils.GetAttribute(node, 'filename')
      if not entry.filename:
        self.errors.append('Filename needs to be provided for each '
                           'priority specifier')
      elif self.app_engine_web_xml.SpecifierEnteredAlready(entry.filename):
        self.errors.append('Cannot have more than one priority specifier with '
                           'the same filename: %s' % entry.filename)
      else:
        try:
          priority = xml_parser_utils.GetAttribute(node, 'priority')
          entry.priority = float(priority) if priority else 1.0
        except ValueError:
          self.errors.append('priority-specifiers must be numbers')
        self.app_engine_web_xml.class_loader_config.append(entry)

  def ProcessUrlStreamHandlerNode(self, node):
    """Processes url stream handler, makes sure it is correct type."""
    new_type = node.text
    urlfetch = self.app_engine_web_xml.URL_HANDLER_URLFETCH
    native = self.app_engine_web_xml.URL_HANDLER_NATIVE
    if new_type not in (urlfetch, native):
      exception_str = 'url-stream-handler must be %s or %s given %s' % (
          urlfetch, native, new_type)
      self.errors.append(exception_str)
    self.app_engine_web_xml.url_stream_handler_type = new_type

  def ProcessUseGoogleConnectorJNode(self, node):
    value = xml_parser_utils.BooleanValue(node.text)
    self.app_engine_web_xml.google_connector_j = value

  def ProcessAutoIdPolicyNode(self, node):
    policy = node.text
    if policy:
      default = self.app_engine_web_xml.DEFAULT_POLICY
      legacy = self.app_engine_web_xml.LEGACY_POLICY
      if policy not in (default, legacy):
        self.errors.append('auto-id-policy must be either "%s" or '
                           '"%s" given %s' % (default, legacy, policy))
        return
      self.app_engine_web_xml.auto_id_policy = policy

  def CheckScalingConstraints(self):
    """Checks that at most one type of scaling is enabled."""
    scaling_num = sum([x is not None for x in [
        self.app_engine_web_xml.basic_scaling,
        self.app_engine_web_xml.automatic_scaling,
        self.app_engine_web_xml.manual_scaling,
        ]])
    if scaling_num > 1:
      self.errors.append('Cannot enable more than one type of scaling')


class AppEngineWebXml(ValueMixin):
  """Organizes and stores data from appengine-web.xml."""
  URL_HANDLER_URLFETCH = 'urlfetch'
  URL_HANDLER_NATIVE = 'native'
  WARMUP_SERVICE = 'warmup'
  DEFAULT_POLICY = 'default'
  LEGACY_POLICY = 'legacy'

  def __init__(self):
    """Initializes an empty AppEngineWebXml object."""
    self.app_id = None
    self.version_id = None
    self.source_language = None
    self.module = None
    self.system_properties = {}
    self.vm_settings = {}
    self.env_variables = {}
    self.instance_class = None
    self.automatic_scaling = None
    self.manual_scaling = None
    self.basic_scaling = None
    self.ssl_enabled = True
    self.sessions_enabled = False
    self.async_session_persistence = False
    self.async_session_persistence_queue_name = None
    self.user_permissions = []
    self.public_root = ''
    self.static_include_pattern = None
    self.inbound_services = set([self.WARMUP_SERVICE])
    self.precompilation_enabled = True
    self.admin_console_pages = []
    self.static_error_handlers = []
    self.threadsafe = False
    self.threadsafe_value_provided = False
    self.codelock = None
    self.vm = False
    self.api_config = None
    self.api_endpoint_ids = []
    self.pagespeed = None
    self.class_loader_config = []
    self.url_stream_handler_type = None
    self.use_google_connector_j = None
    self.static_file_includes = []
    self.static_file_excludes = ['WEB-INF/**', '**.jsp']
    self.resource_file_includes = []
    self.resource_file_excludes = []
    self.auto_id_policy = self.DEFAULT_POLICY
    self._app_root = ''
    self.static_include_pattern = None
    self.static_exclude_pattern = None
    self.resource_include_pattern = None
    self.resource_exclude_pattern = None

  def SpecifierEnteredAlready(self, filename):
    return filename in (entry.filename for entry in self.class_loader_config)

  def IncludesStatic(self, path):
    """Checks whether a given file should be classified as a static file."""
    if not self.static_include_pattern:

      includes_list = ([inc.pattern for inc in self.static_file_includes]
                       or [os.path.join(self.public_root, '**')])
      self.static_include_pattern = self._CreatePatternListRegex(includes_list)

    if self.static_file_excludes:
      if not self.static_exclude_pattern:
        self.static_exclude_pattern = self._CreatePatternListRegex(
            self.static_file_excludes)
      if self.static_exclude_pattern.match(path):
        return False

    return self.static_include_pattern.match(path)

  def IncludesResource(self, path):
    """Checks whether a given file should be classified as a resource file."""
    if not self.resource_include_pattern:
      includes = self.resource_file_includes or ['**']
      self.resource_include_pattern = self._CreatePatternListRegex(includes)

    if self.resource_file_excludes:
      if not self.resource_exclude_pattern:
        self.resource_exclude_pattern = self._CreatePatternListRegex(
            self.resource_file_excludes)
      if self.resource_exclude_pattern.match(path):
        return False

    return self.resource_include_pattern.match(path)

  def _CreatePatternListRegex(self, patterns):
    """Converts a list of patterns into a regex.

    Args:
      patterns: A list of single and double wildcarded path specifying patterns.
    Returns:
      A regular expression matching any of the paths in patterns matching
      one of the files with the path in the subdirectory of the application
      basepath. Ex. if we have and basepath (app_root) of "approot" and
      patterns "foo" and "bar", this returns the compiled regular expression
      of '(^approot\\/foo$|^approot\\/bar$)'.
    """
    regexed_patterns = [self._CreateFileNameRegex(pat) for pat in patterns]
    def _StripLeadingSlashes(pat):
      while pat.startswith('/'):
        pat = pat[1:]
      return pat
    regexed_patterns = [self._CreateFileNameRegex(_StripLeadingSlashes(pat))
                        for pat in patterns]

    app_root_regex = self._CreateFileNameRegex(self.app_root)
    regexed_patterns = ['^%s\\/%s$' % (app_root_regex, pattern_regex)
                        for pattern_regex in regexed_patterns]
    return re.compile('(%s)' % '|'.join(regexed_patterns))

  def _CreateFileNameRegex(self, filename):
    """Converts the object's pattern into an unanchored regular expression.

    Static file patterns can contain single- and double-wildcards. '**'
    represents zero or more directories in a path, and '*' represents zero or
    more characters in a file or directory name.

    Args:
      filename: a resource or static file pattern.
    Returns:
      regular expression version of the pattern. For example, a filename of
      'foo/**.txt' becomes 'foo\\/.*\\.txt'.
    """
    return re.escape(filename).replace('\\*\\*', '.*').replace('\\*', '[^/]*')

  def _SetAppRoot(self, new_root):
    self._app_root = new_root


    self.static_include_pattern = None
    self.static_exclude_pattern = None
    self.resource_include_pattern = None
    self.resource_exclude_pattern = None

  def _GetAppRoot(self):
    return self._app_root

  app_root = property(_GetAppRoot, _SetAppRoot)


class AutomaticScaling(ValueMixin):
  """Instances contain information about automatic scaling settings."""
  pass


class ManualScaling(ValueMixin):
  """Instances contain information about manual scaling settings."""
  pass


class BasicScaling(ValueMixin):
  """Instances contain information about basic scaling settings."""
  pass


class UserPermission(ValueMixin):
  """Instances contain information about user permissions."""
  pass


class AdminConsolePage(ValueMixin):
  """Instances contain information about the admin console page settings."""
  pass


class ErrorHandler(ValueMixin):
  """Instances contain information about error handler settings."""
  pass


class ApiConfig(ValueMixin):
  """Instances contain information about the API config settings."""
  pass


class Pagespeed(ValueMixin):
  """Instances contain information about the pagespeed settings."""


class PrioritySpecifierEntry(ValueMixin):
  """Instances describe a priority specifier entry in appengine-web.xml."""
  pass


class StaticFileInclude(ValueMixin):
  """Instances describe static files to be included in app configuration."""
  pass
