# -*- coding: utf-8 -*-
# DirectAdmin function library
#
# 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
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions
#are met:
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * The names of its contributors may not be used to endorse or
#    promote products derived from this software without specific
#    prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
#FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
#COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
#LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
#ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#POSSIBILITY OF SUCH DAMAGE.
#

# Library functionality:
#
# Automatic configuration of PHP Selector for DirectAdmin
# Create php.ini files for DA PHP version selector
# Create symlink to user data directory
#


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
from builtins import *
import os
import shutil
import cagefslib
from cldetectlib import is_da, get_param_from_file
import secureio
from signals_handlers import sigterm_check
from clcagefslib.selector.panel.da import create_user_php_ini
from clcommon.utils import mod_makedirs


# Configure PHP selector for DA
# Calls from cagefsctl
def configure_selector_for_directadmin():
    # Check - if this DirectAdmin machine
    if not is_da():
        return

    # 1. check file presence
    if not os.path.isfile(cagefslib.NATIVE_CONF):
        if not os.path.isdir(cagefslib.ETC_CL_ALT_PATH):
            mod_makedirs(cagefslib.ETC_CL_ALT_PATH, 0o755)

        shutil.copyfile('/usr/share/cagefs-plugins/directadmin-cagefs/directadmin.native.conf', cagefslib.NATIVE_CONF)
        os.chmod(cagefslib.NATIVE_CONF, 0o644)

    # 2. Determine php version - read /usr/local/directadmin/custombuild/options.conf and find PHP version there
    php_ver = get_param_from_file('/usr/local/directadmin/custombuild/options.conf', 'php1_release', '=')
    php_ver = php_ver.replace('.', '')
    is_lsphp = (get_param_from_file('/usr/local/directadmin/custombuild/options.conf', 'php1_mode', '=') == 'lsphp' or \
                                    get_param_from_file('/usr/local/directadmin/custombuild/options.conf', 'php2_mode', '=') == 'lsphp')


    # 3. Read config File
    cagefslib.read_native_conf()
    if not cagefslib.config_loaded:
        return

    content = cagefslib.orig_binaries

    # 4. modify php line
    if php_ver != '':
        # php = /usr/local/phpNN/bin/php-cgiNN
        content['php'] = '/usr/local/php'+php_ver+'/bin/php-cgi'+php_ver
    else:
        content['php'] = '/usr/local/php5/bin/php-cgi'

    if is_lsphp and not os.path.exists(content['php']):
        shutil.copyfile(content['lsphp'], content['php'])

    # 5. Determine php.ini path from /etc/httpd/conf/extra/httpd-suphp.conf
    httpd_php_ini_path = get_param_from_file('/etc/httpd/conf/extra/httpd-suphp.conf', 'suPHP_ConfigPath')

    if httpd_php_ini_path != '':
        # Path of php.ini determined, insert it to dictionary with PHP version
        if not httpd_php_ini_path.endswith('/'):
            httpd_php_ini_path += '/'

        content['php.ini'] = httpd_php_ini_path + 'php.ini'
    else:
        if php_ver != '':
            content['php.ini'] = '/usr/local/php' + php_ver + '/lib/php.ini'
        else:
            content['php.ini'] = '/usr/local/etc/php5/cgi/php.ini'

    # Check paths existence
    if not os.path.exists(content['php']) or not os.path.exists(content['php.ini']):
        return

    # write to file
    lines = []
    for key in content.keys():
        lines.append(key+'='+content[key])

    cagefslib.write_file(cagefslib.NATIVE_CONF, lines, True)
    cagefslib.config_loaded = False


# Create php.ini for DA
# Call from cagefs
def create_php_ini_for_DA(user_dir, user, php_vers, uid, gid):
    if not is_da():
        return

    cl_user_dir = user_dir + cagefslib.ETC_CL_ALT_PATH + "/" + user + "/php"
    link_name = cl_user_dir + '/php.ini'
    try:
        secureio.set_user_perm(uid, gid)
        if not os.path.isdir(cl_user_dir):
            mod_makedirs(cl_user_dir, 0o755)
        create_user_php_ini(user, php_vers, link_name, True)
    except (OSError, IOError) as e:
        secureio.set_root_perm()
        secureio.logging('Error: ' + str(e), secureio.SILENT_FLAG, True)
        return True

    secureio.set_root_perm()
    return False


# Create symlink to valid php.ini in DirectAdmin user dir
def create_symlink_to_php_ini_for_DA(skeleton_dir):
    sigterm_check()
    if not is_da():
        return

    dest_dir = skeleton_dir + '/usr/local/directadmin/data'
    try:
        if not os.path.isdir(dest_dir):
            mod_makedirs(dest_dir, 0o755)
        link_name = dest_dir + '/users'
        if not (os.path.islink(link_name) and os.readlink(link_name) == cagefslib.ETC_CL_ALT_PATH):
            try:
                os.unlink(link_name)
            except OSError:
                pass
            os.symlink(cagefslib.ETC_CL_ALT_PATH, link_name)
    except (OSError,) as e:
        secureio.logging('Error: ' + str(e), secureio.SILENT_FLAG, 1)
