# -*- coding: utf-8 -*-
# vim:fenc=utf-8

# Copyright (C) 2012-2020 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# X2Go Session Broker is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# X2Go Session Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

"""
X2Go Session Brokers uses many hard-coded defaults, that can be overridden in various ways:

  * environment variables of the same name as the variable name in Python
  * for **SysV init system**: environment variables set in a default configuration
    file under ``/etc/default``; normally the naming scheme is
    ``/etc/default/<executable-name>``
  * for **systemd init system**: in the file ``/etc/x2go/broker/defaults.conf``:
    this file should be installed on your system, the file needs to be provided
    in INI file format
"""

# modules
import os
import socket
import pwd, grp

import logging
from x2gobroker.loggers import logger_broker, logger_access, logger_error, X2GOBROKER_DAEMON_USER
from x2gobroker.loggers import iniconfig_loaded
if iniconfig_loaded:
    from x2gobroker.loggers import iniconfig, iniconfig_section

X2GOBROKER_USER = '<some-user>'
"""The (system) user, X2Go Session Broker runs under. Whether this is a system user or e.g. your own user account depends on what component of the broker is used."""
if 'SPHINX_API_DOCUMENTATION_BUILD' in os.environ.keys():
    X2GOBROKER_USER =  pwd.getpwuid(os.geteuid())[0]

X2GOBROKER_GROUP = '<some-group>'
"""The (system) group, X2Go Session Broker runs under. Whether this is a system user or e.g. the x2gobroker-users group is dependent on what component of the broker is used."""
if 'SPHINX_API_DOCUMENTATION_BUILD' in os.environ.keys():
    X2GOBROKER_GROUP =  grp.getgrgid(pwd.getpwuid(os.geteuid())[3])[0]

os.environ['HOME'] = pwd.getpwuid(os.geteuid())[5]

X2GOBROKER_AGENT_USER="x2gobroker"
"""The system user to use when launching X2Go Broker Agent on remote X2Go Servers."""
if 'X2GOBROKER_DAEMON_GROUP' in os.environ:
    X2GOBROKER_DAEMON_GROUP=os.environ['X2GOBROKER_DAEMON_GROUP']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DAEMON_GROUP'):
    X2GOBROKER_DAEMON_GROUP=iniconfig.get(iniconfig_section, 'X2GOBROKER_DAEMON_GROUP')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_DAEMON_GROUP'):
    X2GOBROKER_DAEMON_GROUP=iniconfig.get('common', 'X2GOBROKER_DAEMON_GROUP')
else:
    X2GOBROKER_DAEMON_GROUP="x2gobroker"
if 'X2GOBROKER_AGENT_USER' in os.environ:
    X2GOBROKER_AGENT_USER=os.environ['X2GOBROKER_AGENT_USER']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_AGENT_USER'):
    X2GOBROKER_AGENT_USER=iniconfig.get(iniconfig_section, 'X2GOBROKER_AGENT_USER')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_AGENT_USER'):
    X2GOBROKER_AGENT_USER=iniconfig.get('common', 'X2GOBROKER_AGENT_USER')

###
### dynamic default values, influencable through os.environ...
###

X2GOBROKER_DEBUG_INTERACTIVELY = False
"""When set to ``True``, the X2Go Broker component this parameter is set for, runs in foreground and debugging mode."""
if 'X2GOBROKER_DEBUG' in os.environ:
    X2GOBROKER_DEBUG = ( os.environ['X2GOBROKER_DEBUG'].lower() in ('1', 'on', 'true', 'yes', ) )
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DEBUG'):
    X2GOBROKER_DEBUG=iniconfig.get(iniconfig_section, 'X2GOBROKER_DEBUG')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_DEBUG'):
    X2GOBROKER_DEBUG=iniconfig.get('common', 'X2GOBROKER_DEBUG')
else:
    X2GOBROKER_DEBUG = False
if 'X2GOBROKER_DEBUG_INTERACTIVELY' in os.environ:
    X2GOBROKER_DEBUG_INTERACTIVELY = ( os.environ['X2GOBROKER_DEBUG_INTERACTIVELY'].lower() in ('1', 'on', 'true', 'yes', ) )
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DEBUG_INTERACTIVELY'):
    X2GOBROKER_DEBUG_INTERACTIVELY=iniconfig.get(iniconfig_section, 'X2GOBROKER_DEBUG_INTERACTIVELY')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_DEBUG_INTERACTIVELY'):
    X2GOBROKER_DEBUG_INTERACTIVELY=iniconfig.get('common', 'X2GOBROKER_DEBUG_INTERACTIVELY')

if 'X2GOBROKER_TESTSUITE' in os.environ:
    X2GOBROKER_TESTSUITE = ( os.environ['X2GOBROKER_TESTSUITE'].lower() in ('1', 'on', 'true', 'yes', ) )
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_TESTSUITE'):
    X2GOBROKER_TESTSUITE=iniconfig.get(iniconfig_section, 'X2GOBROKER_TESTSUITE')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_TESTSUITE'):
    X2GOBROKER_TESTSUITE=iniconfig.get('common', 'X2GOBROKER_TESTSUITE')
else:
    X2GOBROKER_TESTSUITE = False

# enforce debugging for interactive usage
if X2GOBROKER_USER != X2GOBROKER_DAEMON_USER:
    X2GOBROKER_DEBUG = True

# raise log levels to CRITICAL if we are running the unittests...
if X2GOBROKER_TESTSUITE:
    logger_broker.setLevel(logging.CRITICAL)
    logger_access.setLevel(logging.CRITICAL)
    logger_error.setLevel(logging.CRITICAL)

X2GOBROKER_CONFIG = "/etc/x2go/x2gobroker.conf"
"""Location of X2Go Broker\'s global configuration file."""
if 'X2GOBROKER_CONFIG' in os.environ:
    X2GOBROKER_CONFIG = os.environ['X2GOBROKER_CONFIG']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_CONFIG'):
    X2GOBROKER_CONFIG=iniconfig.get(iniconfig_section, 'X2GOBROKER_CONFIG')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_CONFIG'):
    X2GOBROKER_CONFIG=iniconfig.get('common', 'X2GOBROKER_CONFIG')

X2GOBROKER_SESSIONPROFILES = "/etc/x2go/broker/x2gobroker-sessionprofiles.conf"
"""Location of the INI file based broker backend \'s session profiles configuration file."""
if 'X2GOBROKER_SESSIONPROFILES' in os.environ:
    X2GOBROKER_SESSIONPROFILES = os.environ['X2GOBROKER_SESSIONPROFILES']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_SESSIONPROFILES'):
    X2GOBROKER_SESSIONPROFILES=iniconfig.get(iniconfig_section, 'X2GOBROKER_SESSIONPROFILES')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_SESSIONPROFILES'):
    X2GOBROKER_SESSIONPROFILES=iniconfig.get('common', 'X2GOBROKER_SESSIONPROFILES')

X2GOBROKER_AGENT_CMD = "/usr/lib/x2go/x2gobroker-agent"
"""Path to the X2Go Broker Agent executable on remote X2Go Servers."""
if 'X2GOBROKER_AGENT_CMD' in os.environ:
    X2GOBROKER_AGENT_CMD = os.environ['X2GOBROKER_AGENT_CMD']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_AGENT_CMD'):
    X2GOBROKER_AGENT_CMD=iniconfig.get(iniconfig_section, 'X2GOBROKER_AGENT_CMD')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_AGENT_CMD'):
    X2GOBROKER_AGENT_CMD=iniconfig.get('common', 'X2GOBROKER_AGENT_CMD')

if os.path.isdir('/run/x2gobroker'):
    RUNDIR = '/run'
else:
    RUNDIR = '/var/run/x2gobroker'
X2GOBROKER_AUTHSERVICE_SOCKET="{run}/x2gobroker/x2gobroker-authservice.socket".format(run=RUNDIR)
"""Location of the X2Go Broker Auth Service's authentication socket file."""
if 'X2GOBROKER_AUTHSERVICE_SOCKET' in os.environ:
    X2GOBROKER_AUTHSERVICE_SOCKET=os.environ['X2GOBROKER_AUTHSERVICE_SOCKET']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_AUTHSERVICE_SOCKET'):
    X2GOBROKER_AUTHSERVICE_SOCKET=iniconfig.get(iniconfig_section, 'X2GOBROKER_AUTHSERVICE_SOCKET')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_AUTHSERVICE_SOCKET'):
    X2GOBROKER_AUTHSERVICE_SOCKET=iniconfig.get('common', 'X2GOBROKER_AUTHSERVICE_SOCKET')

if os.path.isdir('/run/x2gobroker'):
    RUNDIR = '/run'
else:
    RUNDIR = '/var/run/x2gobroker'
X2GOBROKER_LOADCHECKER_SOCKET="{run}/x2gobroker/x2gobroker-loadchecker.socket".format(run=RUNDIR)
"""Location of the X2Go Broker Load Checker's communication socket file."""
if 'X2GOBROKER_LOADCHECKER_SOCKET' in os.environ:
    X2GOBROKER_LOADCHECKER_SOCKET=os.environ['X2GOBROKER_LOADCHECKER_SOCKET']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_LOADCHECKER_SOCKET'):
    X2GOBROKER_LOADCHECKER_SOCKET=iniconfig.get(iniconfig_section, 'X2GOBROKER_LOADCHECKER_SOCKET')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_LOADCHECKER_SOCKET'):
    X2GOBROKER_LOADCHECKER_SOCKET=iniconfig.get('common', 'X2GOBROKER_LOADCHECKER_SOCKET')

X2GOBROKER_DEFAULT_BACKEND = "inifile"
"""The broker backend to use by default."""
if 'X2GOBROKER_DEFAULT_BACKEND' in os.environ:
    X2GOBROKER_DEFAULT_BACKEND = os.environ['X2GOBROKER_DEFAULT_BACKEND']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DEFAULT_BACKEND'):
    X2GOBROKER_DEFAULT_BACKEND=iniconfig.get(iniconfig_section, 'X2GOBROKER_DEFAULT_BACKEND')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_DEFAULT_BACKEND'):
    X2GOBROKER_DEFAULT_BACKEND=iniconfig.get('common', 'X2GOBROKER_DEFAULT_BACKEND')


DAEMON_BIND_ADDRESS = ""
"""Bind address for the X2Go Session Broker standalone daemon."""
if 'DAEMON_BIND_ADDRESS' in os.environ:
    DAEMON_BIND_ADDRESS = os.environ['DAEMON_BIND_ADDRESS']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'DAEMON_BIND_ADDRESS'):
    DAEMON_BIND_ADDRESS = iniconfig.get(iniconfig_section, 'DAEMON_BIND_ADDRESS')
elif iniconfig_loaded and iniconfig.has_option('daemon', 'DAEMON_BIND_ADDRESS'):
    DAEMON_BIND_ADDRESS = iniconfig.get('daemon', 'DAEMON_BIND_ADDRESS')

X2GOBROKER_SSL_CERTFILE = ""
"""Path to the SSL/TLS public certificate file."""
if 'X2GOBROKER_SSL_CERTFILE' in os.environ:
    X2GOBROKER_SSL_CERTFILE = os.environ['X2GOBROKER_SSL_CERTFILE']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_SSL_CERTFILE'):
    X2GOBROKER_SSL_CERTFILE = iniconfig.get(iniconfig_section, 'X2GOBROKER_SSL_CERTFILE')
elif iniconfig_loaded and iniconfig.has_option('daemon', 'X2GOBROKER_SSL_CERTFILE'):
    X2GOBROKER_SSL_CERTFILE = iniconfig.get('daemon', 'X2GOBROKER_SSL_CERTFILE')

X2GOBROKER_SSL_KEYFILE = ""
"""Path to the SSL/TLS secret key file."""
if 'X2GOBROKER_SSL_KEYFILE' in os.environ:
    X2GOBROKER_SSL_KEYFILE = os.environ['X2GOBROKER_SSL_KEYFILE']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_SSL_KEYFILE'):
    X2GOBROKER_SSL_KEYFILE = iniconfig.get(iniconfig_section, 'X2GOBROKER_SSL_KEYFILE')
elif iniconfig_loaded and iniconfig.has_option('daemon', 'X2GOBROKER_SSL_KEYFILE'):
    X2GOBROKER_SSL_KEYFILE = iniconfig.get('daemon', 'X2GOBROKER_SSL_KEYFILE')

###
### static / hard-coded defaults
###

if socket.gethostname().find('.') >= 0:
    X2GOBROKER_HOSTNAME = socket.gethostname()
else:
    X2GOBROKER_HOSTNAME = socket.gethostbyaddr(socket.gethostname())[0]

# the home directory of the user that the daemon/cgi runs as
X2GOBROKER_HOME = os.path.normpath(os.path.expanduser('~{broker_uid}'.format(broker_uid=X2GOBROKER_DAEMON_USER)))
"""Home directory of the user that an X2Go Broker component runs under."""

# defaults for X2Go Sessino Broker configuration file
X2GOBROKER_CONFIG_DEFAULTS = {
    'global': {
        # legacy support for X2Go Session Broker << 0.0.3.0
        # the check-credentials parameter has been slit up into the two params above
        'check-credentials': True,
        # use these two instead of check-credentials...
        'require-password': True,
        'require-cookie': False,
        'use-static-cookie': False,
        'auth-timeout': 36000,
        'cookie-directory': '/var/lib/x2gobroker/cookies',
        'verify-ip': True,
        'pre_auth_scripts': [],
        'post_auth_scripts': [],
        'select_session_scripts': [],
        'my-cookie': None,
        'my-cookie-file': '/etc/x2go/broker/x2gobroker.authid',
        'enable-plain-output': True,
        'enable-json-output': True,
        'enable-uccs-output': False,
        'my-uccs-url-base': 'http://localhost:8080/',
        'default-auth-mech': 'pam',
        'default-user-db': 'libnss',
        'default-group-db': 'libnss',
        'ignore-primary-group-memberships': True,
        'default-session-autologin': False,
        'default-authorized-keys': '%h/.x2go/authorized_keys',
        'default-sshproxy-authorized-keys': '%h/.x2go/authorized_keys',
        'default-agent-query-mode': 'NONE',
        'default-agent-hostkey-policy': 'RejectPolicy',
        'default-portscan-x2goservers': True,
        'default-use-load-checker': False,
        'load-checker-intervals': 300,
    },
    'broker_base': {
        'enable': False,
    },
    'broker_zeroconf': {
        'enable': False,
        'auth-mech': 'pam',
        'user-db': 'libnss',
        'group-db': 'libnss',
        'desktop-shell': 'KDE',
        'load-checker': False,
    },
    'broker_inifile': {
        'enable': True,
        'session-profiles': '/etc/x2go/broker/x2gobroker-sessionprofiles.conf',
        'auth-mech': '',
        'user-db': '',
        'group-db': '',
        'use-load-checker': True,
    },
    'broker_ldap': {
        'enable': False,
        'auth-mech': 'ldap',
        'user-db': 'ldap',
        'group-db': 'ldap',
        'uri': 'ldap://localhost:389',
        'base': 'dc=example,dc=org',
        'user-search-filter': '(&(objectClass=posixAccount)(uid=*))',
        'host-search-filter': '(&(objectClass=ipHost)(serial=X2GoServer)(cn=*))',
        'group-search-filter': '(&(objectClass=posifxGroup)(cn=*))',
        'starttls': False,
        'agent-query-mode': 'SSH',
        'load-checker': True,
    },
}
"""Defaults of the global configuration file, see ``X2GOBROKER_CONFIG``."""


X2GO_DESKTOP_SESSIONS= [
    'KDE',
    'GNOME',
    'XFCE',
    'CINNAMON',
    'MATE',
    'XFCE',
    'LXDE',
    'TRINITY',
    'UNITY',
    'ICEWM',
    'OPENBOX',
    'XDMCP',
]
"""Desktop environment session types supported by X2Go."""

# defaults for X2Go Sessino Broker session profiles file
X2GOBROKER_SESSIONPROFILE_DEFAULTS = {
    'DEFAULT': {
        'command': 'TERMINAL',
        'kdrive': False,
        'defsndport': True,
        'useiconv': False,
        'iconvfrom': 'UTF-8',
        'height': 600,
        'export': '',
        'quality': 9,
        'fullscreen': False,
        'layout': '',
        'useexports': True,
        'width': 800,
        'speed': 2,
        'soundsystem': 'pulse',
        'print': True,
        'type': 'auto',
        'sndport': 4713,
        'xinerama': True,
        'variant': '',
        'usekbd': True,
        'fstunnel': True,
        'applications': ['TERMINAL','WWWBROWSER','MAILCLIENT','OFFICE'],
        'multidisp': False,
        'sshproxyport': 22,
        'sound': True,
        'rootless': True,
        'iconvto': 'UTF-8',
        'soundtunnel': True,
        'dpi': 96,
        'sshport': 22,
        'setdpi': 0,
        'pack': '16m-jpeg',
        'user': 'BROKER_USER',
        'host': [ 'localhost', ],
        'directrdp': False,
        'acl-users-allow': [],
        'acl-users-deny': [],
        'acl-users-order': '',
        'acl-groups-allow': [],
        'acl-groups-deny': [],
        'acl-groups-order': '',
        'acl-clients-allow': [],
        'acl-clients-deny': [],
        'acl-clients-order': '',
        'acl-any-order': 'deny-allow',
    },
}
"""Default setting of a broker'ish session profile."""

X2GOBROKER_LATEST_UCCS_API_VERSION = 5
"""Latest known API of the UCCS protocol that we support."""
