<?php

namespace Aps\App\Joomla;

require_once __DIR__ . '/bootstrap.php';

class Configurator
{
    public function execute()
    {
        $data = array(
            'dbtype' => apsGetDatabaseType(),
            'host' => apsGetDatabaseHost(),
            'user' => getenv('DB_main_LOGIN'),
            'password' => getenv('DB_main_PASSWORD'),
            'db' => getenv('DB_main_NAME'),
            'dbprefix' => getenv('DB_main_PREFIX') ?: 'jos_',
        );

        // use default com_config component
        \JLoader::registerPrefix('Config', JPATH_ADMINISTRATOR . '/components/com_config');
        \JLoader::registerPrefix('Config', JPATH_ROOT . '/components/com_config');

        $this->fixDatabaseSettings($data);

        $model = new \ConfigModelApplication;
        if (!$model->save($data)) {
            throw new \Exception();
        }

        $this->updateAdminOption();
    }

    protected function fixDatabaseSettings($data)
    {
        // 1)
        // db-connect checker use password from old config (???)
        //
        // @see \ConfigModelApplication::save
        \JFactory::getConfig()->set('password', $data['password']);

        // 2)
        // ConfigModelApplication constructor read config, initialise db-driver
        // and driver into internal instances storage:
        // \ConfigModelApplication::__construct -> \ConfigModelCms::__construct
        // \JModelDatabase::__construct
        // \JModelDatabase::loadDb
        // \JFactory::getDbo
        // \JFactory::createDbo
        // \JFactory::getConfig
        // \JDatabaseDriver::getInstance -> \JDatabaseDriver::$instances
        //
        // @see \JFactory::createDbo
        \JFactory::getConfig()->set('host', $data['host']);
        \JFactory::getConfig()->set('user', $data['user']);
        \JFactory::getConfig()->set('db', $data['db']);
        \JFactory::getConfig()->set('dbprefix', $data['dbprefix']);
        \JFactory::getConfig()->set('dbtype', $data['dbtype']);
    }

    protected function updateAdminOption()
    {
        $u = trim(getenv('SETTINGS_admin_name'));
        $p = \JUserHelper::hashPassword(getenv('SETTINGS_admin_password'));

        $db = \JFactory::getDBO();
        $set = array(
            $db->quoteName('password') . ' = ' . $db->quote($p),
        );
        $query = $db->getQuery(true)
            ->update($db->quoteName('#__users'))
            ->set($set)
            ->where($db->quoteName('username') . ' = ' . $db->quote($u));
        $db->setQuery($query);

        if (!$db->execute()) {
            throw new \Exception('Admin account not found: ' . $u);
        }
    }
}
