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


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():
    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])
        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)
        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()
