#!/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 datetime
import os.path
import logging
import re
import traceback
from AmbariConfig import AmbariConfig
import ConfigParser

HADOOP_ROOT_DIR = "/usr/hdp"
HADOOP_PERM_REMOVE_LIST = ["current"]
HADOOP_ITEMDIR_REGEX = "(\d\.){3}\d-\d{4}"
logger = logging.getLogger(__name__)

class HostCheckReportFileHandler:

  HOST_CHECK_FILE = "hostcheck.result"
  HOST_CHECK_CUSTOM_ACTIONS_FILE = "hostcheck_custom_actions.result"

  def __init__(self, config=None):
    self.hostCheckFilePath = None
    
    if config is None:
      config = self.resolve_ambari_config()
      
    hostCheckFileDir = config.get('agent', 'prefix')
    self.hostCheckFilePath = os.path.join(hostCheckFileDir, self.HOST_CHECK_FILE)
    self.hostCheckCustomActionsFilePath = os.path.join(hostCheckFileDir, self.HOST_CHECK_CUSTOM_ACTIONS_FILE)
    
  def resolve_ambari_config(self):
    try:
      config = AmbariConfig()
      if os.path.exists(AmbariConfig.getConfigFile()):
        config.read(AmbariConfig.getConfigFile())
      else:
        raise Exception("No config found, use default")

    except Exception, err:
      logger.warn(err)
    return config
    
  def writeHostChecksCustomActionsFile(self, structuredOutput):
    if self.hostCheckCustomActionsFilePath is None:
      return
    
    try:
      logger.info("Host check custom action report at " + self.hostCheckCustomActionsFilePath)
      config = ConfigParser.RawConfigParser()
      config.add_section('metadata')
      config.set('metadata', 'created', str(datetime.datetime.now()))
      
      if 'installed_packages' in structuredOutput.keys():
        items = []
        for itemDetail in structuredOutput['installed_packages']:
          items.append(itemDetail['name'])
        config.add_section('packages')
        config.set('packages', 'pkg_list', ','.join(map(str, items)))

      if 'existing_repos' in structuredOutput.keys():
        config.add_section('repositories')
        config.set('repositories', 'repo_list', ','.join(structuredOutput['existing_repos']))
        
      self.removeFile(self.hostCheckCustomActionsFilePath)
      self.touchFile(self.hostCheckCustomActionsFilePath)
      with open(self.hostCheckCustomActionsFilePath, 'wb') as configfile:
        config.write(configfile)
    except Exception, err:
      logger.error("Can't write host check file at %s :%s " % (self.hostCheckCustomActionsFilePath, err.message))
      traceback.print_exc()

  def _stack_list_directory(self):
    """
    Return filtered list of <stack-root> directory allowed to be removed
    :rtype list
    """

    if not os.path.exists(HADOOP_ROOT_DIR):
      return []

    matcher = re.compile(HADOOP_ITEMDIR_REGEX)  # pre-compile regexp
    folder_content = os.listdir(HADOOP_ROOT_DIR)
    remove_list = []

    remlist_items_count = 0

    for item in folder_content:
      full_path = "%s%s%s" % (HADOOP_ROOT_DIR, os.path.sep, item)
      if item in HADOOP_PERM_REMOVE_LIST:
        remove_list.append(full_path)
        remlist_items_count += 1

      if matcher.match(item) is not None:
        remove_list.append(full_path)
        remlist_items_count += 1

    # if remove list have same length as target folder, assume that they are identical
    if remlist_items_count == len(folder_content):
      remove_list.append(HADOOP_ROOT_DIR)

    return remove_list

  def writeHostCheckFile(self, hostInfo):
    if self.hostCheckFilePath is None:
      return

    try:
      logger.debug("Host check report at " + self.hostCheckFilePath)
      config = ConfigParser.RawConfigParser()
      config.add_section('metadata')
      config.set('metadata', 'created', str(datetime.datetime.now()))

      if 'existingUsers' in hostInfo.keys():
        items = []
        items2 = []
        for itemDetail in hostInfo['existingUsers']:
          items.append(itemDetail['name'])
          items2.append(itemDetail['homeDir'])
        config.add_section('users')
        config.set('users', 'usr_list', ','.join(items))
        config.set('users', 'usr_homedir_list', ','.join(items2))

      if 'alternatives' in hostInfo.keys():
        items = []
        items2 = []
        for itemDetail in hostInfo['alternatives']:
          items.append(itemDetail['name'])
          items2.append(itemDetail['target'])
        config.add_section('alternatives')
        config.set('alternatives', 'symlink_list', ','.join(items))
        config.set('alternatives', 'target_list', ','.join(items2))

      if 'stackFoldersAndFiles' in hostInfo.keys():
        items = []
        for itemDetail in hostInfo['stackFoldersAndFiles']:
          items.append(itemDetail['name'])
        items += self._stack_list_directory()
        config.add_section('directories')
        config.set('directories', 'dir_list', ','.join(items))

      if 'hostHealth' in hostInfo.keys():
        if 'activeJavaProcs' in hostInfo['hostHealth'].keys():
          items = []
          for itemDetail in hostInfo['hostHealth']['activeJavaProcs']:
            items.append(itemDetail['pid'])
          config.add_section('processes')
          config.set('processes', 'proc_list', ','.join(map(str, items)))

      self.removeFile(self.hostCheckFilePath)
      self.touchFile(self.hostCheckFilePath)
      with open(self.hostCheckFilePath, 'wb') as configfile:
        config.write(configfile)
    except Exception, err:
      logger.error("Can't write host check file at %s :%s " % (self.hostCheckFilePath, err.message))
      traceback.print_exc()

  def removeFile(self, path):
    if os.path.isfile(path):
      logger.debug("Removing old host check file at %s" % path)
      os.remove(path)

  def touchFile(self, path):
    if not os.path.isfile(path):
      logger.debug("Creating host check file at %s" % path)
      open(path, 'w').close()


