#!/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.

# Script to check if hcat_server is reachable.
# Checks if databases can be enumerated, and databases can be created/dropped.

import sys, os, random, string, logging, logging.handlers
from optparse import OptionParser
from decimal import *

def generate_random_id( length=8, charset=(string.ascii_lowercase + string.digits) ):
  return ''.join(random.choice(charset) for i in range(length))

# PING-DB related "constants".
HCAT_CHECK_DATABASE_NAME = 'hcat_ping_' + generate_random_id()
HCAT_CHECK_DATABASE_LOCATION = '/tmp/hcat_ping/' + HCAT_CHECK_DATABASE_NAME

ATTEMPT_CLEANUP=False
logger = logging.getLogger()
logLevels = [ logging.ERROR, logging.INFO, logging.DEBUG ]
THE_CHECK_COMMAND = ""

def check_unique_database_name():
  global HCAT_CHECK_DATABASE_NAME
  global HCAT_CHECK_DATABASE_LOCATION
  # If directory already exists, pick a new database-name/location.
  while run_command_quietly("hadoop dfs -ls " + HCAT_CHECK_DATABASE_LOCATION) == 0:
    HCAT_CHECK_DATABASENAME = 'hcat_ping_' + generate_random_id()
    HCAT_CHECK_DATABASE_LOCATION = '/tmp/hcat_ping/' + HCAT_CHECK_DATABASE_NAME

def run_command_quietly(command):
  global logger
  os.putenv("HADOOP_HOME_WARN_SUPPRESS", "true")
  return_code = os.system(command + " >/dev/null 2>&1")
  logger.debug("Running command: " + command + " ... returned " + str(return_code))
  return return_code

def run_hcat_command(command):
  return run_command_quietly(THE_CHECK_COMMAND + " -e \"" + command + "\" ")

def init_ping_command():
  global THE_CHECK_COMMAND

  if is_command_in_path("hcat"):
    THE_CHECK_COMMAND = "hcat"
  elif is_command_in_path("hive"):
    THE_CHECK_COMMAND = "hive"
  else:
    logger.error("Could not find hcat or hive in $PATH. Can't connect to \
                 HCatalog Server.")
    sys.exit(2)

def is_command_in_path(command):
  return run_command_quietly("which " + command) == 0

def list_databases():
  global logger
  return_code = run_hcat_command("SHOW DATABASES") 
  if return_code != 0:
    logger.debug("Could not list-databases.")
    return False

  return True

def create_database():
  check_unique_database_name()
  global ATTEMPT_CLEANUP
  global logger
  ATTEMPT_CLEANUP = True  # State is changing. Must attempt cleanup.

  create_db = "CREATE DATABASE " + HCAT_CHECK_DATABASE_NAME + " LOCATION '"+ HCAT_CHECK_DATABASE_LOCATION + "'"
  list_db_dir = "hadoop dfs -ls " + HCAT_CHECK_DATABASE_LOCATION

  if run_hcat_command(create_db) !=0 or run_command_quietly(list_db_dir) != 0:
    logger.debug("Creating database failed.")
    return False
  
  return True

def drop_database(suppressError):
  global logger
  drop_db = "DROP DATABASE " + HCAT_CHECK_DATABASE_NAME
  list_db_dir = "hadoop dfs -ls " + HCAT_CHECK_DATABASE_LOCATION

  if run_hcat_command(drop_db) != 0 or run_command_quietly(list_db_dir) == 0:
    if not suppressError:
      logger.debug("Dropping database failed.")
    return False

  return True

def cleanup():
  drop_database(True)
  run_command_quietly( "hadoop dfs -rmr -skipTrash " + HCAT_CHECK_DATABASE_LOCATION )

def parse_options():
  global logger
  global logLevels

  streamHandler = logging.StreamHandler()
  logger.addHandler(streamHandler)

  parser = OptionParser()
  parser.add_option("-v", "--verbose", dest="verbosity_level", 
                    help="Controls verbosity of output to LEVEL (0-2)", metavar="LEVEL", default="1")
  parser.add_option("-f", "--file",    dest="filename",        
                    help="Write output to FILE", metavar="FILE")
  (options, args) = parser.parse_args()

  level = int(Decimal(options.verbosity_level))
  if not level in range(0,3):
    print "Invalid verbosity level. Should be in range [0, 2]."
    sys.exit(3)

  if options.filename:
    logger.removeHandler(streamHandler)
    handler = logging.handlers.RotatingFileHandler(options.filename,
                                                   maxBytes=1024*1024,
                                                   backupCount=3)
    logger.addHandler(handler)
  else:
    handler = streamHandler

  formatter = logging.Formatter("%(asctime)s %(filename)s:%(lineno)d %(levelname)s - %(message)s")
  handler.setFormatter( formatter )
  logger.setLevel( logLevels[level] )

def main(*args):
  global logger
  try:
    try:
      parse_options()
      init_ping_command()

      # Not making assumptions on availability of ternary.
      if list_databases() and create_database() and drop_database(False):
        logger.info("HCatalog Server is running fine.")
        return 0 # OK!
      else:
        logger.critical("HCatalog Server could not be contacted.")
        return 2  # Critical!
    except SystemExit, sysExit:
      return sysExit
    except Exception, e:
      logger.exception("Could not determine if HCatalog Server is running.")
      return 3  # Unknown Error.

  finally: # Nested try. Pre-2.5 Python won't allow try-except-finally.
    if ATTEMPT_CLEANUP:
      cleanup()
    
if __name__ == '__main__':
  sys.exit( main(*sys.argv) )
      
