if [[ $EUID -gt 0 ]]; then
    echo "####################################################"
    echo "#                                                  #"
    echo "#  ERROR: You must be root to run this script!!!!  #"
    echo "#                                                  #"
    echo "####################################################"
    exit 1
fi

export PATH=$PATH:/usr/local/bin:/usr/local/sbin

# XXX a bit brutal but otherwise it cannot work, without tty enabled.  
if [ -f /etc/sudoers ]; then
  sed -i "/requiretty/d" /etc/sudoers
fi

# Include Additional Functions
function download_playbook {
    if [ ! -f /etc/opt/slapcache.cfg ]; then
      slapcache-conf
    fi
    DFILE=$(mktemp -d -t "$(basename "$0")"-XXXXXXXXXXXX)
    TFILE="archive.tar.gz"
    cd "$DFILE" || exit 1
    slapcache-download --destination=$TFILE
    tar -xzvf $TFILE
    rm $TFILE
}

# Determine what system we are running on.  This provides ``os_VENDOR``,
# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
# and ``DISTRO``
GetDistro

if [[ ${DISTRO} =~ (-.) ]] && [[ -f /etc/debian_version ]]; then
  apt_get install lsb-release
  GetDistro
fi

# Warn users who aren't on an explicitly supported distro, but allow them to
# override check and attempt installation with ``export FORCE=yes``
if [[ ! ${DISTRO} =~ (stretch|buster|bullseye|bookworm|xenial|bionic|focal|jammy|Kylin-v10.|rhel7|Linuxmint-21.1) ]]; then
    echo "WARNING: this script has not been tested on $DISTRO"
    if [[ "$FORCE" != "yes" ]]; then
        die $LINENO "If you wish to run this script anyway run with FORCE=yes"
    fi
fi

# Starting from Debian 12, we need this variable to install eggs with pip at system level
if [[ "$os_VENDOR" =~ (Debian) && "$os_RELEASE" > 11 ]]; then
  export PIP_BREAK_SYSTEM_PACKAGES=1
fi

is_package_installed unzip || install_package unzip
is_package_installed openssl || install_package openssl
is_package_installed ansible || install_package ansible

if [[ $DISTRO = sle15.6 ]]; then
  # Python 3.11 is in a separate module, called Python 3, while the base system has Python 3.6.
  # If the Python 3 module is enabled, we assume that the user has preference for it.
  # Otherwise, we install the base packages.
  is_package_installed python311-pip || is_package_installed python3-pip || install_package python311-pip || install_package python3-pip 
  pip3 install --upgrade pip
elif ! is_ubuntu || [[ $DISTRO = wheezy || $DISTRO == jessie || $DISTRO == stretch || $DISTRO == xenial || $DISTRO == bionic ]]; then
  is_package_installed python-pip || install_package python-pip
  pip install --upgrade "pip < 21.0"
else
  # Ansible is using python3 now
  is_package_installed python3-pip || install_package python3-pip
  pip3 install --upgrade pip
fi

if is_ubuntu && [[ $DISTRO == focal || $DISTRO == buster ]]; then
  # install python2 in distro where python2 is not installed by default and ansible python interpreter is still python2
  is_package_installed python || install_package python
fi

if is_fedora && [[ $DISTRO == "f26" ]]; then
  is_package_installed python2-rpm || install_package python2-rpm
  is_package_installed yum || install_package yum
fi

if is_ubuntu && [[ $DISTRO == "trusty" ]]; then
  is_package_installed python-apt || install_package python-apt
  is_package_installed python-pycurl || install_package python-pycurl
fi

if is_ubuntu && [[ $DISTRO == "vivid" ]]; then
  is_package_installed python-apt || install_package python-apt
  is_package_installed python-pycurl || install_package python-pycurl
fi

if [[ $DISTRO == "LinuxMint-17.2" ]]; then
  is_package_installed python-apt || install_package python-apt
  is_package_installed python-pycurl || install_package python-pycurl
fi

ANSIBLE_PLUGIN_LOCATION="/usr/share/ansible_plugins/callback_plugins/"
mkdir -p $ANSIBLE_PLUGIN_LOCATION
/bin/cat << EOF > $ANSIBLE_PLUGIN_LOCATION/log_parse.py
from __future__ import absolute_import
import os
import time
import json
import ansible

baseModule = object
ANSIBLE_VERSION = 1

if hasattr(ansible, 'plugins') and  hasattr(ansible.plugins, 'callback'):
  baseModule = ansible.plugins.callback.CallbackBase
  ANSIBLE_VERSION = 2

class CallbackModule(baseModule):
    """
    logs playbook results, per host, in /var/log/ansible/hosts
    """
    log_path = '/var/log/ansible/hosts'
    fd_list = {}

    def __init__(self):

      if ANSIBLE_VERSION > 1:
        super(CallbackModule, self).__init__()

      if not os.path.exists(self.log_path):
        os.makedirs(self.log_path)
      else:
        for filename in os.listdir(self.log_path):
          filepath = os.path.join(self.log_path, filename)
          if os.path.isfile(filepath):
            os.unlink(filepath)

    def writeLog(self, host, category, content):
      if category not in self.fd_list:
        self.fd_list[category] = open(
          os.path.join(self.log_path, '%s_%s' % (host, category)), "a"
        )

      self.fd_list[category].write(content + '\n')

    def log(self, host, category, data, ignore_errors=False):
      if host == "localhost":
        host = "127.0.0.1" # keep compatibility

      if type(data) is dict:
        if '_ansible_verbose_override' in data:
          # avoid logging extraneous data
          return

        content = json.dumps(data)

        if ignore_errors:
          category = '%s_IGNORED' % category
        self.writeLog(host, category, content)

    def _stats(self, stats):
      for key in self.fd_list:
        self.fd_list[key].close()

    def runner_on_failed(self, host, res, ignore_errors=False):
      self.log(host, 'FAILED', res, ignore_errors)

    def runner_on_ok(self, host, res):
      self.log(host, 'OK', res)

    def runner_on_skipped(self, host, item=None):
      pass

    def runner_on_unreachable(self, host, res):
      self.log(host, 'UNREACHABLE', res)

    def runner_on_async_failed(self, host, res, jid):
      self.log(host, 'ASYNC_FAILED', res)

    def playbook_on_import_for_host(self, host, imported_file):
      self.log(host, 'IMPORTED', imported_file)

    def playbook_on_not_import_for_host(self, host, missing_file):
      self.log(host, 'NOTIMPORTED', missing_file)

    def playbook_on_stats(self, stats):
      self._stats(stats)

EOF

ansible localhost -m pip -a name=setuptools --connection=local
ansible localhost -m pip -a name=wheel --connection=local
ansible localhost -m pip -a name=slapcache --connection=local
ansible localhost -m pip -a name=requests --connection=local

if [ ! -f /usr/share/ansible_plugins/mitogen.zip ]; then
    wget -O /usr/share/ansible_plugins/mitogen.zip https://shacache.nxdcdn.com/3a935ff257ddc0ad4e0f23d71681e026f14f309f4bed0a8e2a217da9b294be2c676196703f0dde856ece49d711d0221deae70812f035b24aa5cdd0ca02790e85
    unzip /usr/share/ansible_plugins/mitogen.zip -d /usr/share/ansible_plugins/mitogen/
    mv /usr/share/ansible_plugins/mitogen/mitogen-*/* /usr/share/ansible_plugins/mitogen/
fi
