#!/usr/bin/env python

"""
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 imp
import logging
import os
import re
from alerts.base_alert import BaseAlert
from resource_management.core.environment import Environment
from resource_management.libraries.functions.curl_krb_request import KERBEROS_KINIT_TIMER_PARAMETER
from ambari_agent import Constants

logger = logging.getLogger("ambari_alerts")

class ScriptAlert(BaseAlert):

  def __init__(self, alert_meta, alert_source_meta, config):

    """ ScriptAlert reporting structure is output from the script itself """

    alert_source_meta['reporting'] = {
      'ok': { 'text': '{0}' },
      'warning': { 'text': '{0}' },
      'critical': { 'text': '{0}' },
      'unknown': { 'text': '{0}' }
    }

    super(ScriptAlert, self).__init__(alert_meta, alert_source_meta, config)

    self.path = None
    self.stacks_dir = None
    self.common_services_dir = None
    self.host_scripts_dir = None
    self.extensions_dir = None
    self.path_to_script = None
    self.parameters = {}

    # will force a kinit even if klist says there are valid tickets (4 hour default)
    self.kinit_timeout = long(config.get('agent', 'alert_kinit_timeout', BaseAlert._DEFAULT_KINIT_TIMEOUT))

    if 'path' in alert_source_meta:
      self.path = alert_source_meta['path']

    if 'common_services_directory' in alert_source_meta:
      self.common_services_dir = alert_source_meta['common_services_directory']

    if 'stacks_directory' in alert_source_meta:
      self.stacks_dir = alert_source_meta['stacks_directory']

    if 'host_scripts_directory' in alert_source_meta:
      self.host_scripts_dir = alert_source_meta['host_scripts_directory']

    if 'extensions_directory' in alert_source_meta:
      self.extensions_dir = alert_source_meta['extensions_directory']

    # convert a list of script parameters, like timeouts, into a dictionary
    # so the the scripts can easily lookup the data
    if 'parameters' in alert_source_meta:
      parameters = alert_source_meta['parameters']
      for parameter in parameters:
        if 'name' not in parameter or 'value' not in parameter:
          continue

        # create the dictionary value
        parameter_name = parameter['name']
        parameter_value = parameter['value']
        self.parameters[parameter_name] = parameter_value

    # pass in some basic parameters to the scripts
    self.parameters[KERBEROS_KINIT_TIMER_PARAMETER] = self.kinit_timeout

  def _collect(self):
    cmd_module = self._load_source()

    if cmd_module is not None:
      configurations = {}

      try:
        tokens = cmd_module.get_tokens()
        if tokens is not None:
          # for each token, if there is a value, store in; otherwise don't store
          # a key with a value of None
          for token in tokens:
            value = self._get_configuration_value(token)
            if value is not None:
              configurations[token] = value
      except AttributeError:
        # it's OK if the module doesn't have get_tokens() ; no tokens will
        # be passed in so hopefully the script doesn't need any
        logger.debug("The script {0} does not have a get_tokens() function".format(str(cmd_module)))

      # try to get basedir for scripts
      # it's needed for server side scripts to properly use resource management
      matchObj = re.match( r'((.*)services(.*)package)', self.path_to_script)
      if matchObj:
        basedir = matchObj.group(1)
        with Environment(basedir, tmp_dir=Constants.AGENT_TMP_DIR, logger=logging.getLogger('ambari_alerts')) as env:
          result = cmd_module.execute(configurations, self.parameters, self.host_name)
      else:
        result = cmd_module.execute(configurations, self.parameters, self.host_name)

      loggerMsg = "[Alert][{0}] Failed with result {2}: {3}".format(
        self.get_name(), self.path_to_script, result[0], result[1])

      if result[0] == self.RESULT_CRITICAL:
        logger.error(loggerMsg)
      elif result[0] == self.RESULT_WARNING or result[0] == self.RESULT_UNKNOWN:
        logger.debug(loggerMsg)

      return result
    else:
      return (self.RESULT_UNKNOWN, ["Unable to execute script {0}".format(self.path)])


  def _load_source(self):
    if self.path is None and self.stack_path is None and self.host_scripts_dir is None:
      raise Exception("The attribute 'path' must be specified")

    paths = self.path.split('/')
    self.path_to_script = self.path

    # if the path doesn't exist and stacks dir is defined, try that
    if not os.path.exists(self.path_to_script) and self.stacks_dir is not None:
      self.path_to_script = os.path.join(self.stacks_dir, *paths)

    # if the path doesn't exist and common services dir is defined, try that
    if not os.path.exists(self.path_to_script) and self.common_services_dir is not None:
      self.path_to_script = os.path.join(self.common_services_dir, *paths)

    # if the path doesn't exist and the host script dir is defined, try that
    if not os.path.exists(self.path_to_script) and self.host_scripts_dir is not None:
      self.path_to_script = os.path.join(self.host_scripts_dir, *paths)

    # if the path doesn't exist and the extensions dir is defined, try that
    if not os.path.exists(self.path_to_script) and self.extensions_dir is not None:
      self.path_to_script = os.path.join(self.extensions_dir, *paths)

    # if the path can't be evaluated, throw exception
    if not os.path.exists(self.path_to_script) or not os.path.isfile(self.path_to_script):
      raise Exception(
        "Unable to find '{0}' as an absolute path or part of {1} or {2}".format(self.path,
          self.stacks_dir, self.host_scripts_dir))

    if logger.isEnabledFor(logging.DEBUG):
      logger.debug("[Alert][{0}] Executing script check {1}".format(
        self.get_name(), self.path_to_script))

          
    if (not self.path_to_script.endswith('.py')):
      logger.error("[Alert][{0}] Unable to execute script {1}".format(
        self.get_name(), self.path_to_script))

      return None

    return imp.load_source(self._get_alert_meta_value_safely('name'), self.path_to_script)


  def _get_reporting_text(self, state):
    '''
    Always returns {0} since the result of the script alert is a rendered string.
    This will ensure that the base class takes the result string and just uses
    it directly.

    :param state: the state of the alert in uppercase (such as OK, WARNING, etc)
    :return:  the parameterized text
    '''
    return '{0}'
