<?php

defined('APS_BOOTSTRAP') || define('APS_BOOTSTRAP', __DIR__ . '/bootstrap-administrator.php');

function apsGetDatabaseType()
{
    $driver = getenv('DB_main_TYPE');
    // plan A:
    return ('mysql' == $driver) ? 'mysqli' : $driver;
    // plan B:
    return ('mysql' == $driver) ? 'pdomysql' : $driver;
}

function apsGetDatabaseHost()
{
    $host = getenv('DB_main_HOST');

    // special thanks for POA
    $port = getenv('DB_main_PORT');
    empty($port) || ($host .= ':' . $port);

    return $host;
}

defined('_JEXEC') || define('_JEXEC', 'APS');

// overwrite default function - add exit code
function jexit($message = 0)
{
    debug_print_backtrace();
    if (!is_numeric($message)) {
        echo $message, PHP_EOL;
    }
    print_r(array(__FUNCTION__ => $message));
    exit(1);
}

require_once APS_BOOTSTRAP;

/**
 * lock display page in exists handler
 * @see /libraries/cms.php
 * set_exception_handler(array('JErrorPage', 'render'));
 */
set_exception_handler(null);

class JApplicationAps extends \Joomla\Application\AbstractApplication
{
    public function __call($name, $arguments)
    {
        print_r(array('----------------------------------------------------', $name, $arguments));
        debug_print_backtrace();
        exit(1);
    }

    public function close($code = 0)
    {
        jexit($code);
    }

    protected function doExecute()
    {
    }

    // \JApplicationCms::enqueueMessage
    public function enqueueMessage($msg, $type = 'message')
    {
        print_r(array($type => $msg));
        debug_print_backtrace();
    }

    public function getLocaliseAdmin()
    {
        return array('admin' => array(), 'site' => array());
    }

    /**
     * @copypasto! \JApplicationWeb::flushAssets
     */
    public function flushAssets()
    {
        $version = new JVersion;
        $version->refreshMediaVersion();
    }

    /**
     * @copypasto! \JApplicationCms::getUserState
     * use in upgrade action
     *
     * #0  JApplicationAps->__call(getUserState, Array ([0] => com_cache.cache.filter.search))
     * #1  JApplicationAps->getUserState(com_cache.cache.filter.search) called at [.libraries/legacy/model/list.php:69
     * #2  JModelList->getUserStateFromRequest(...) called at [.administrator/components/com_cache/models/cache.php:79]
     * #3  CacheModelCache->populateState() called at [.libraries/legacy/model/legacy.php:439]
     * #4  JModelLegacy->getState(client_id) called at [.administrator/components/com_cache/models/cache.php:176]
     * #5  CacheModelCache->getCache() called at [.administrator/components/com_cache/models/cache.php:234]
     * #6  CacheModelCache->clean() called at [.administrator/components/com_admin/script.php:1886]
     * #7  JoomlaInstallerScript->cleanJoomlaCache() called at [.administrator/components/com_admin/script.php:41]
     * #8  JoomlaInstallerScript->update(...) called at [.administrator/components/com_joomlaupdate/models/default.php:694]
     * #9  JoomlaupdateModelDefault->finaliseUpgrade() called at [./scripts/Upgrader.php:35]
     */
    public function getUserState($key, $default = null)
    {
        return $default;
    }

    /**
     * @copypasto! \JApplicationCms::getUserStateFromRequest
     * use in upgrade action
     *
     * #0  JApplicationAps->__call(getUserStateFromRequest, Array ([0] => com_cache.cache.filter,[1] => filter,[2] => Array (),[3] => array))
     * #1  JApplicationAps->getUserStateFromRequest(com_cache.cache.filter, filter, Array (), array) called at [.libraries/legacy/model/list.php:488]
     * #2  JModelList->populateState(group, asc) called at [.administrator/components/com_cache/models/cache.php:86]
     * #3  CacheModelCache->populateState() called at [.libraries/legacy/model/legacy.php:439]
     * #4  JModelLegacy->getState(client_id) called at [.administrator/components/com_cache/models/cache.php:176]
     * #5  CacheModelCache->getCache() called at [.administrator/components/com_cache/models/cache.php:234]
     * #6  CacheModelCache->clean() called at [.administrator/components/com_admin/script.php:1886]
     * #7  JoomlaInstallerScript->cleanJoomlaCache() called at [.administrator/components/com_admin/script.php:41]
     * #8  JoomlaInstallerScript->update(...) called at [.administrator/components/com_joomlaupdate/models/default.php:694]
     * #9  JoomlaupdateModelDefault->finaliseUpgrade() called at [./scripts/Upgrader.php:37]
     */
    public function getUserStateFromRequest($key, $request, $default = null, $type = 'none')
    {
        return $default;
    }

    /**
     * @copypasto! \JApplicationCms::isClient
     * use in upgrade action
     *
     * #0  JApplicationAps->__call(isClient, Array ([0] => site))
     * #1  JApplicationAps->isClient(site) called at [./libraries/cms/language/multilang.php:39]
     * #2  JLanguageMultilang::isEnabled() called at [./libraries/legacy/table/menu.php:183]
     * #3  JTableMenu->store() called at [./libraries/joomla/table/table.php:915]
     * #4  JTable->save(Array (...)) called at [.administrator/components/com_admin/script.php:158]
     * #5  JoomlaInstallerScript->postflight(update, JInstaller Object (...)) called at [.administrator/components/com_joomlaupdate/models/default.php:769]
     * #6  JoomlaupdateModelDefault->finaliseUpgrade() called at [/usr/local/psa/var/apspackages/./scripts/Upgrader.php:35]
     * #7  Aps\App\Joomla\Upgrader->execute(3.6.5, 27) called at [/usr/local/psa/var/apspackages/./scripts/configure:33]
     */
    public function isClient($identifier)
    {
        if ('site' == $identifier) {
            return false;
        }

        $this->__call(__FUNCTION__, func_get_args());
    }
}

/**
 * Class JSessionAps is workaround for
 * PHP Fatal error: Call to a member function get() on a non-object in .../libraries/joomla/session/handler/joomla.php on line 71
 * in installation
 */
class JSessionAps //extends \JSession
{
    public $apsUserId;
    public $apsUser;

    public function get($name, $default = null, $namespace = 'default')
    {
        // @see \InstallationModelDatabase::generateRandUserId
        if ('randUserId' == $name) {
            if (!$this->apsUserId) {
                $this->apsUserId = mt_rand(1, 1000);
            }
            return $this->apsUserId;
        }

        // @see \JFactory::getUser
        if ('user' == $name) {
            if (!$this->apsUser) {
                $identifier = (string)getenv('SETTINGS_admin_name');
                $this->apsUser = \JUser::getInstance($identifier);
            }
            return $this->apsUser;
        }

        // \InstallationModelDatabase::initialise 186,217,224
        if ('remoteDbFile' == $name) {
            return true;
        }
        if (('remoteDbFileWrittenByJoomla' == $name) || ('remoteDbFileUnwritable' == $name)) {
            return false;
        }
        if  ('remoteDbFileTestsPassed' == $name){
            return true;
        }
        throw new \Exception('APS install/upgrade MUST not call session. Requested: ' . $name);
    }

    public function set($name, $value = null, $namespace = 'default')
    {
        // @see \InstallationModelConfiguration::createConfiguration
        if ('setup.config' == $name) {
            return null;
        }

        // @see \InstallationModelDatabase::resetRandUserId();
        if ('randUserId' == $name) {
            $this->apsUserId = $value;
            return null;
        }

        return parent::set($name, $value, $namespace);
    }

    public function getState()
    {
        // @see \JoomlaInstallerScript::flushSessions
    }

    public function restart()
    {
        // @see \JoomlaInstallerScript::flushSessions
    }
}

// @todo ??? mock JSession::checkToken() and call native controllers with JApplicationAps
\JFactory::$application = new JApplicationAps();
