#!/opt/alt/python37/bin/python3 -bb
# coding=utf-8
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2020 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#

# Cloudlinux + sender daemon control utility

import sys
import subprocess
import syslog
import os
import requests
import json
import re
import logging

from urllib.parse import urlparse

from clcommon.lib.jwt_token import jwt_token_check
from clcommon.lib.cmt_utils import (
    is_cmt_disabled,
    is_client_enabled,
    log_request_error_debug_info
)
from clcommon.lib.consts import (
    DISABLE_CMT_DIR,
    DISABLE_CMT_FILE,
    PUSHGATEWAY_ADDRESS
)
from clsentry import init_sentry_client
from lve_utils import PKG_VERSION

SETUP_CLPLUS_FILE = '/usr/share/cloudlinux/cl_plus/setup_clplus'
PKG_VERSION_TINY = re.sub(r'\.el\w(h?)\.', '.elX.', PKG_VERSION)

# https://cl.sentry.cloudlinux.com/settings/cloudlinux_os/projects/userland
SENTRY_DSN = 'https://9713d1296f804031b058b8f2d789d7ac:' \
             '8ddacae32d8246cf8b25cf826bf3fc0a@cl.sentry.cloudlinux.com/12'

BAD_JWT_WARNING = \
    "WARNING: it looks that this server is still marked as not having CloudLinux plus license. " \
    "Command that you run will still work, but have no " \
    "effect until CloudLinux plus license will be detected. " \
    "If you are sure that this server must have CloudLinux plus license, " \
    "try to run `rhn_check` and this command again. If warning still appears, " \
    "contact CloudLinux support for help (https://www.cloudlinux.com/support)."

NON_ACTIVATED_CM_WARN = \
    "Looks like you haven't activated statistics collection " \
    "via the Centralized Monitoring UI.\n" \
    "Check this link for more detailed instructions:\n" \
    "https://docs.cloudlinux.com/cloudlinux-os-plus/#installation-2" \
    " (paragraph 4). Command that you run will still work, but have no " \
    "effect until you activate Centralized Monitoring " \
    "using button on https://cm.cloudlinux.com."


def main():
    logger = logging.getLogger()
    try:
        init_sentry_client('manage_clplus', PKG_VERSION_TINY, SENTRY_DSN, custom_length=7000)
    except Exception as e:
        # just in case sentry was not initialized - do not log anything to console
        handler = logging.StreamHandler()
        handler.setLevel(logging.CRITICAL)
        logger.addHandler(handler)
        syslog.syslog(syslog.LOG_ERR, f'Failed to init sentry client: {e}')
    component = 'manage_cl_plus'
    if '--help' in sys.argv:
        print(
            "--help - will show this page\n"
            "enable - will turn on cl_plus service (this option will remove file '/etc/cl_plus/.disable')\n"
            "disable - will turn off cl_plus service (this option will add file '/etc/cl_plus/.disable')"
        )
        sys.exit(0)
    # we check this constraints before so we could avoid
    # unnecessary requests to backend
    is_valid, jwt_err_msg, _ = jwt_token_check()
    if 'enable' in sys.argv:
        if not is_valid:
            print(BAD_JWT_WARNING)
        try:
            os.remove(DISABLE_CMT_FILE)
        except OSError:
            pass
    elif 'disable' in sys.argv:
        if not is_valid:
            print(BAD_JWT_WARNING)
        # create .disable file
        if not os.path.isdir(DISABLE_CMT_DIR):
            os.mkdir(DISABLE_CMT_DIR, 0o644)
        open(DISABLE_CMT_FILE, "w+").close()

    is_disabled = is_cmt_disabled()
    _is_client_enabled = False
    try:
        if is_valid and not is_disabled:
            _is_client_enabled = is_client_enabled(raise_exception=True)
            # Warning, if enable mode was called without UI activation
            if 'enable' in sys.argv and not _is_client_enabled:
                print(NON_ACTIVATED_CM_WARN)
    except requests.exceptions.RequestException as e:
        http_response = e.response
        if http_response is None or http_response.status_code not in (requests.codes.UNAUTHORIZED,
                                                                      requests.codes.FORBIDDEN):
            # 'https://cm.cloudlinux.com' -> cm.cloudlinux.com
            cm_domain = urlparse(PUSHGATEWAY_ADDRESS).hostname
            log_request_error_debug_info(component, logger, e, cm_domain)
        sys.exit(-1)
    except (
        KeyError,
        json.JSONDecodeError,
        OSError,
        IOError
    ) as e:
        logging.error("manage_clplus error: %s", str(e),
                      extra={'fingerprint': [component, e.__class__.__name__]})
        sys.exit(-1)

    if not(is_valid and not is_disabled and _is_client_enabled):
        # JWT token absent or invalid - remove daemons
        if os.path.isfile(SETUP_CLPLUS_FILE):
            subprocess.call(["yum", "-y", "remove", "cl-end-server-tools"])
        sys.exit(0)
    # JWT token check OK - install daemons
    if not os.path.isfile(SETUP_CLPLUS_FILE):
        subprocess.call(["yum", "-y", "install", "cl-end-server-tools"])


if __name__ == "__main__":
    main()
