#!/opt/cloudlinux/venv/bin/python3 -bb
# -*- coding: utf-8 -*-

# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT


from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import subprocess

import cldetectlib as detect
import os
import sys
import re

from clcommon.cpapi import admin_packages
from clcommon.public_hooks import setup_logger_and_sentry

from clhooklib import log_error, check_cpanel_version, LVE_EXTENSION_HOOKS
from clcommon.public_hooks.bundle import cpanel
from clcommon.cpapi.cpapiexceptions import CPAPIExternalProgramFailed
from clcommon.lib.cledition import lve_supported_or_exit

SCRIPT_NAME = os.path.basename(__file__)
PKG_DIR = '/var/cpanel/packages'
CPANEL_EXTENSIONS_DIR = '/var/cpanel/packages/extensions'
HOOK_SCRIPT_PATH = '/scripts/cl_pkg_modify_hook.py'
CPANEL_DOCROOT = '/usr/local/cpanel/whostmgr/docroot/3rdparty/cloudlinux'

_LEGACY_HOOKS_TO_REMOVE = (
    cpanel.Hook(HOOK_SCRIPT_PATH, 'Whostmgr', 'Accounts::change_package', 'post'),
    cpanel.Hook(HOOK_SCRIPT_PATH, 'Whostmgr', 'Accounts::Create',         'post'),
)


@lve_supported_or_exit  # temporary disabled until CLPRO-2013 is done
def main():
    # in fact this is only wrapper for
    # hooks logic located in cllib
    # so we can just use cllib sentry here
    setup_logger_and_sentry()

    if detect.is_cpanel() and check_cpanel_version():
        if os.path.isfile(HOOK_SCRIPT_PATH):
            cpanel.remove_hooks(_LEGACY_HOOKS_TO_REMOVE)
            try:
                os.remove(HOOK_SCRIPT_PATH)
            except OSError:
                pass

        try:
            packages = admin_packages(raise_exc=True)
        except (OSError, CPAPIExternalProgramFailed):
            log_error(SCRIPT_NAME, 'Can\'t get package list')
            sys.exit(1)
        for package in packages:
            if package != '':
                pkg_file = PKG_DIR + '/' + package
                pkg_file = pkg_file.replace(' ', '\ ')
                with open(pkg_file, 'r') as f:
                    content = f.read()

                lines = content.split('\n')

                for i, line in enumerate(lines):
                    if line.startswith('_PACKAGE_EXTENSIONS='):
                        # Retrieve the string part with the config value
                        config_line = line.split('=', maxsplit=1)[1].strip()

                        # Remove standalone "lve" words from the config value
                        config_line = re.sub(r'(?:^|\s+)lve(?=\s+|$)', '', config_line)
                        # Uses a lookahead expression to avoid consuming the whitespace;
                        # otherwise substrings like "lve lve" would be replaced with "lve", not removed

                        # Eliminate extraneous whitespace
                        config_line = ' '.join(config_line.split())

                        lines[i] = f'_PACKAGE_EXTENSIONS={config_line}'

                with open(pkg_file, 'w') as file:
                    file.write('\n'.join(lines))
        try:
            if os.path.exists(CPANEL_EXTENSIONS_DIR + '/lve'):
                os.remove(CPANEL_EXTENSIONS_DIR + '/lve')
        except OSError:
            log_error(SCRIPT_NAME, 'Can\'t remove default settings to lve extension')
        try:
            if os.path.exists(CPANEL_EXTENSIONS_DIR + '/lve.tt2'):
                os.remove(CPANEL_EXTENSIONS_DIR + '/lve.tt2')
        except OSError:
            log_error(SCRIPT_NAME, 'Can\'t remove lve extension')
        try:
            if os.path.exists(CPANEL_DOCROOT + '/lve_ext_scritps.js'):
                os.remove(CPANEL_EXTENSIONS_DIR + '/lve_ext_scritps.js')
        except OSError:
            log_error(SCRIPT_NAME, 'Can\'t remove lve extension js')
        try:
            os.rmdir(CPANEL_EXTENSIONS_DIR)  # delete only empty directory
        except OSError:
            pass

        cpanel.remove_hooks(LVE_EXTENSION_HOOKS)


if __name__ == '__main__':
    main()
