#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Huawei Technologies Co.,Ltd.
#
# openGauss is licensed under Mulan PSL v2.
# You can use this software according to the terms
# and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#
#          http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
# ----------------------------------------------------------------------------

from pickle import STOP
import subprocess
from re import sub
import sys
import getopt

sys.path.append(sys.path[0] + "/../")
from gspylib.common.GaussLog import GaussLog
from gspylib.common.ErrorCode import ErrorCode
from gspylib.common.LocalBaseOM import LocalBaseOM
from gspylib.common.ParameterParsecheck import Parameter
from domain_utils.cluster_file.cluster_log import ClusterLog
from domain_utils.domain_common.cluster_constants import ClusterConstants
from base_utils.os.env_util import EnvUtil
from gspylib.component.DSS.dss_checker import DssConfig
from base_utils.os.crontab_util import CrontabUtil
from domain_utils.cluster_file.cluster_dir import ClusterDir
from gspylib.common.Common import DefaultValue

class CMOptConst:
    START = "start"
    STOP = "stop"
        

class LocalCmOpt(LocalBaseOM):
    """
    The class is used to do perform start
    """

    def __init__(self):
        """
        function: initialize the parameters
        input: NA
        output: NA
        """
        super(LocalCmOpt, self).__init__()
        self.user = ""
        self.dataDir = ""
        self.time_out = 300
        self.logFile = ""
        self.logger = None
        self.installPath = ""
        self.security_mode = ""
        self.cluster_number = None
        self.action = ""
        
    def usage(self):
        """
General options:
    -U USER                  the database program and cluster owner")
    -D DATADIR               data directory of instance
    -t SECS                  seconds to wait
    -l LOGFILE               log file
    -?, --help               show this help, then exit
    --action                 start or stop
        """
        print(self.usage.__doc__)

    def parseCommandLine(self):
        """
        function: Check input parameters
        input : NA
        output: NA
        """
        try:
            opts, args = getopt.getopt(sys.argv[1:], "U:D:R:l:h?",
                                       ["help", "action="])
        except getopt.GetoptError as e:
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] % str(e))

        if (len(args) > 0):
            GaussLog.exitWithError(
                ErrorCode.GAUSS_500["GAUSS_50000"] % str(args[0]))

        for key, value in opts:
            if key == "-U":
                self.user = value
            elif key == "-D":
                self.dataDir = value
            elif key == "-t":
                self.time_out = int(value)
            elif key == "-l":
                self.logFile = value
            elif key == "-R":
                self.installPath = value
            elif key == "--action":
                self.action = value
            elif key == "--help" or key == "-h" or key == "-?":
                self.usage()
                sys.exit(0)
            else:
                GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"]
                                       % key)
            Parameter.checkParaVaild(key, value)

        if self.user == "":
            GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"]
                                   % 'U' + ".")
        if self.logFile == "":
            self.logFile = ClusterLog.getOMLogPath(
                ClusterConstants.LOCAL_LOG_FILE, self.user, self.installPath)

    def __initLogger(self):
        """
        function: Init logger
        input : NA
        output: NA
        """
        self.logger = GaussLog(self.logFile, "LocalCMOperation")

    def init(self):
        """
        function: constructor
        """
        self.__initLogger()
        self.readConfigInfo()
        
    def do_stop_components(self):
        cmd = ""
        if CrontabUtil.check_user_crontab_permission():
            crondesc = subprocess.getoutput("crontab -l | grep om_monitor")
            if not crondesc.startswith("#"):
                cmd += "crontab -l | sed '/om_monitor/s/^/#/' | crontab -;"
        cmd += f"pkill -9 om_monitor -U {self.user};"
        cmd += f"pkill -9 cm_agent -U {self.user};"
        cmd += f"pkill -9 cm_server -U {self.user};"
        
        self.logger.log(f"stop cm components: {cmd}")
        status, output = subprocess.getstatusoutput(cmd)
        self.logger.log(status, output)
           
           
    def do_start_components(self):
        mpprc_file = EnvUtil.getEnv(DefaultValue.MPPRC_FILE_ENV)
        app_path = ClusterDir.getInstallDir(self.user)
        log_path = ClusterLog.getOMLogPath(DefaultValue.OM_MONITOR_DIR_FILE,
                                             self.user,
                                             app_path)
        cmd = ""
        if CrontabUtil.check_user_crontab_permission():
            crondesc = subprocess.getoutput("crontab -l | grep om_monitor")
            if crondesc.startswith("#"):
                cmd = "crontab -l | sed '/om_monitor/s/^#//' | crontab -;"
        if mpprc_file != "" and mpprc_file is not None:
            cmd += "source ~/.bashrc;source %s; nohup %s/bin/om_monitor -L %s " \
                  ">>/dev/null 2>&1 &" % (mpprc_file, app_path, log_path)
        else:
            cmd += "source ~/.bashrc; nohup %s/bin/om_monitor -L %s >>" \
                  "/dev/null 2>&1 &" % (app_path, log_path)
        
        self.logger.log(f"start cm components: {cmd}")
        status, output = subprocess.getstatusoutput(cmd)
        self.logger.log(status, output)
        

    def do_operate(self):
        """
        function: do start|stop CM components
        input  : NA
        output : NA
        """
        print(self.action)
        if self.action == CMOptConst.START:
            self.do_start_components()
        elif self.action == CMOptConst.STOP:
            self.do_stop_components()
        else:
            self.logger.warn(f"action [{self.action}] is unknown, Do nothing.")
            

def main():
    """
    main function
    """
    try:
        opt = LocalCmOpt()
        opt.parseCommandLine()
        opt.init()
    except Exception as e:
        GaussLog.exitWithError(ErrorCode.GAUSS_536["GAUSS_53608"] % str(e))
    try:
        opt.do_operate()
    except Exception as e:
        GaussLog.exitWithError(str(e))


if __name__ == "__main__":
    main()
