"""
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 os
import re
from resource_management.core.logger import Logger
from resource_management.core.exceptions import Fail
from resource_management.core.resources.system import Execute
from resource_management.core import shell
from resource_management.libraries.functions import format
from resource_management.libraries.functions import stack_select
from resource_management.libraries.functions import StackFeature
from resource_management.libraries.functions.stack_features import check_stack_feature
from resource_management.libraries.functions.version import format_stack_version


def deregister():
  """
  Runs the "hive --service hiveserver2 --deregister <version>" command to
  de-provision the server in preparation for an upgrade. This will contact
  ZooKeeper to remove the server so that clients that attempt to connect
  will be directed to other servers automatically. Once all
  clients have drained, the server will shutdown automatically.

  However, since Ambari does not support Hive Server rolling upgrades due to the port change
  affecting Hive Clients not using the ZK discovery service, the daemon might be forcefully
  killed before it has been deregistered and drained.

  This function will obtain the Kerberos ticket if security is enabled.
  :return:
  """
  import params

  Logger.info('HiveServer2 executing "deregister" command to complete upgrade...')

  if params.security_enabled:
    kinit_command=format("{kinit_path_local} -kt {smoke_user_keytab} {smokeuser_principal}; ")
    Execute(kinit_command,user=params.smokeuser)

  # calculate the current hive server version
  current_hiveserver_version = _get_current_hiveserver_version()
  if current_hiveserver_version is None:
    raise Fail('Unable to determine the current HiveServer2 version to deregister.')

  # deregister
  hive_execute_path = params.execute_path
  # If upgrading, the upgrade-target hive binary should be used to call the --deregister command.
  # If downgrading, the downgrade-source hive binary should be used to call the --deregister command.
  # By now <stack-selector-tool> has been called to set 'current' to target-stack
  if params.downgrade_from_version is not None:
    hive_execute_path = _get_hive_execute_path(params.downgrade_from_version)

  command = format('hive --config {hive_server_conf_dir} --service hiveserver2 --deregister ' + current_hiveserver_version)
  Execute(command, user=params.hive_user, path=hive_execute_path, tries=1 )


def _get_hive_execute_path(stack_version_formatted):
  """
  Returns the exact execute path to use for the given stack-version.
  This method does not return the "current" path
  :param stack_version_formatted: Exact stack-version to use in the new path
  :return: Hive execute path for the exact stack-version
  """
  import params

  hive_execute_path = params.execute_path
  formatted_stack_version = format_stack_version(stack_version_formatted)
  if formatted_stack_version and check_stack_feature(StackFeature.ROLLING_UPGRADE, formatted_stack_version):
    # hive_bin
    new_hive_bin = format('{stack_root}/{stack_version_formatted}/hive/bin')
    if (os.pathsep + params.hive_bin) in hive_execute_path:
      hive_execute_path = hive_execute_path.replace(os.pathsep + params.hive_bin, os.pathsep + new_hive_bin)
    # hadoop_bin_dir
    new_hadoop_bin = stack_select.get_hadoop_dir_for_stack_version("bin", stack_version_formatted)
    old_hadoop_bin = params.hadoop_bin_dir
    if new_hadoop_bin and len(new_hadoop_bin) > 0 and (os.pathsep + old_hadoop_bin) in hive_execute_path:
      hive_execute_path = hive_execute_path.replace(os.pathsep + old_hadoop_bin, os.pathsep + new_hadoop_bin)
  return hive_execute_path


def _get_current_hiveserver_version():
  """
  Runs "hive --version" and parses the result in order
  to obtain the current version of hive.

  :return:  the hiveserver2 version, returned by "hive --version"
  """
  import params

  try:
    # When downgrading the source version should be the version we are downgrading from
    source_version = params.version_for_stack_feature_checks
    if params.downgrade_from_version is not None:
      source_version = params.downgrade_from_version

    hive_execute_path = _get_hive_execute_path(source_version)
    version_hive_bin = params.hive_bin
    formatted_source_version = format_stack_version(source_version)
    if formatted_source_version and check_stack_feature(StackFeature.ROLLING_UPGRADE, formatted_source_version):
      version_hive_bin = format('{stack_root}/{source_version}/hive/bin')
    command = format('{version_hive_bin}/hive --version')
    return_code, output = shell.call(command, user=params.hive_user, path=hive_execute_path)
  except Exception, e:
    Logger.error(str(e))
    raise Fail('Unable to execute hive --version command to retrieve the hiveserver2 version.')

  if return_code != 0:
    raise Fail('Unable to determine the current HiveServer2 version because of a non-zero return code of {0}'.format(str(return_code)))

  match = re.search('^(Hive) ([0-9]+.[0-9]+.\S+)', output, re.MULTILINE)

  if match:
    current_hive_server_version = match.group(2)
    return current_hive_server_version
  else:
    raise Fail('The extracted hiveserver2 version "{0}" does not matching any known pattern'.format(output))


