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

try:
    import os
    import json
    import sys
    import subprocess
    from hawqpylib.HAWQ_HELP import *
    from hawqpylib.hawqlib import *
    from gppylib.gplog import get_default_logger
except ImportError, e:
    sys.exit('ERROR: Cannot import modules.  Please check that you '
                 'have sourced greenplum_path.sh.  Detail: ' + str(e))

global hawq_home, source_hawq_env, logger


def print_version():
    print 'HAWQ version $Revision$'
    sys.exit(0)


def local_run(cmd):
    '''Execute shell command on local machine.'''
    result = subprocess.Popen(cmd, shell=True).wait()
    return result

def check_master_or_standby_host(master_host_name='localhost', standby_host_name='None'):
    if not check_hostname_equal(master_host_name, user = ""):
       if standby_host_name.lower() != 'none':
           if not check_hostname_equal(standby_host_name, user = ""):
               return False
           else:
               return True
       else:
               return False
    else:
        return True

def main():
    logger = get_default_logger()
    hawq_home = os.getenv('GPHOME')
    if not hawq_home:
        print "HAWQ home directory not defined, please check GPHOME settings."
        sys.exit(1)

    hawqsite = HawqXMLParser(hawq_home)
    hawqsite.get_all_values()
    hawq_dict = hawqsite.hawq_dict
    master_host_name = hawq_dict['hawq_master_address_host']
    cluster_host_list = list()
    cluster_host_list.append(master_host_name)
    if 'hawq_standby_address_host' in hawq_dict:
        standby_host_name = hawq_dict['hawq_standby_address_host']
        cluster_host_list.append(standby_host_name)
    else:
        standby_host_name = 'None'

    segments_host_list = parse_hosts_file(hawq_home)
    for host in segments_host_list:
        cluster_host_list.append(host)

    result = 0

    cluster_type_list = ('cluster', 'segment', 'master', 'standby', 'allsegments')
    cluster_init_list = ('cluster', 'segment', 'master', 'standby')
    source_hawq_env = ". %s/greenplum_path.sh" % hawq_home

    if len(sys.argv) > 2:
        hawq_command = sys.argv[1]
        second_arg = sys.argv[2]
        sub_args_list = sys.argv[2:]
        # Password can have special characters like semicolon (;), quotes(", ') etc, convert input password to a string
        if hawq_command == 'ssh-exkeys' and '-p' in sub_args_list:
            password_index = sub_args_list.index('-p') + 1
            if len(sub_args_list) > password_index:
                sub_args_list[password_index] = json.dumps(sub_args_list[password_index])

        for index, arg in enumerate(sub_args_list):
            if " " in arg:
                sub_args_list[index] = '"%s"' % arg

        sub_args = " ".join(sub_args_list)
    elif len(sys.argv) > 1:
        hawq_command = sys.argv[1]
        second_arg = ''
        sub_args = ''
    else:
        hawq_command = ''
        second_arg = ''
        sub_args = ''

    if (second_arg == 'cluster' or (hawq_command in ('remove', 'filespace', 'state'))):
        if not check_hostname_equal(master_host_name, user = ""):
            print "This can be run on master host only"
            sys.exit(1)

    if (hawq_command == 'config' or
       (hawq_command in ('init', 'activate') and second_arg == 'standby')):
        if not check_master_or_standby_host(master_host_name, standby_host_name):
            print "This can be run only on master or standby host"
            sys.exit(1)

    if hawq_command == "start":
        if second_arg not in cluster_type_list:
            print START_HELP
            sys.exit(1)
        cmd = "%s; hawq_ctl %s %s" % (source_hawq_env, hawq_command, sub_args)
        result = local_run(cmd)
    elif hawq_command == "stop":
        if second_arg not in cluster_type_list:
            print STOP_HELP
            sys.exit(1)
        # Prints deprecation warning when using old syntax "hawq stop <object> -u" to reload GUC
        if len(sub_args.split("-")) > 1:
            if "-u" in sub_args or "--reload" in sub_args or "u" in sub_args.split("-")[1]:
                logger.info("hawq stop <object> -u is being deprecated and replaced by 'hawq reload <object>'")
                logger.info("Current syntax will work, please use 'hawq reload <object>' going forward.")
        cmd = "%s; hawq_ctl %s %s" % (source_hawq_env, hawq_command, sub_args)
        result = local_run(cmd)
    elif hawq_command == "reload":
        if second_arg not in cluster_type_list:
            print RELOAD_CONFIG_HELP
            sys.exit(1)
        hawq_command="stop"
        sub_args_list.append("-u")
        sub_args=" ".join(sub_args_list)
        cmd = "%s; hawq_ctl %s %s" % (source_hawq_env, hawq_command, sub_args)
        result = local_run(cmd)
    elif hawq_command == "init":
        if second_arg not in cluster_init_list:
            print INIT_HELP
            sys.exit(1)
        cmd = "%s; hawq_ctl %s %s" % (source_hawq_env, hawq_command, sub_args)
        result = local_run(cmd)
    elif hawq_command == "restart":
        if second_arg not in cluster_type_list:
            print RESTART_HELP
            sys.exit(1)
        cmd = "%s; hawq_ctl stop %s" % (source_hawq_env, sub_args)
        check_return_code(local_run(cmd))
        cmd = "%s; hawq_ctl start %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "activate":
        if second_arg in ['', 'help', '--help', '-h']:
            print ACTIVE_HELP
            sys.exit(1)
        cmd = "%s; hawq_ctl %s %s" % (source_hawq_env, hawq_command, sub_args)
        result = local_run(cmd)
    elif hawq_command == "config":
        if second_arg in ['', 'help', '--help', '-h']:
            print CONFIG_HELP
            sys.exit(1)
        cmd = "%s; hawqconfig %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "extract":
        cmd = "%s; hawqextract %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "check":
        cmd = "%s; gpcheck %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "checkperf":
        cmd = "%s; gpcheckperf %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "load":
        cmd = "%s; gpload %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "filespace":
        cmd = "%s; hawqfilespace %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "state":
        cmd = "%s; hawqstate %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "ssh":
        cmd = "%s; gpssh %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "ssh-exkeys":
        cmd = "%s; gpssh-exkeys %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "scp":
        cmd = "%s; gpscp %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "register":
        if second_arg in ['', 'help', '--help', '-h']:
            doc_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../docs/cli_help/','hawqregister_help')
            with open(doc_path, 'r') as f:
                REGISTER_HELP = f.read()
            print REGISTER_HELP
            sys.exit(1)
        cmd = "%s; hawqregister %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "upgrade":
        cmd = "%s; hawqupgrade %s" % (source_hawq_env, sub_args)
        result = local_run(cmd)
    elif hawq_command == "version" or hawq_command == "--version":
        print_version()
    else:
        print COMMON_HELP
        sys.exit(1)
    check_return_code(result)

if __name__ == '__main__':
    main()
