<?php

namespace apexl\Io\modules\install;
use apexl\Config\Singleton;
use apexl\Io\includes\System;
use apexl\Io\services\pathUtility;

use apexl\Vault\Vault;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class installController {

    protected $path;
    protected $database;

    public function __construct(pathUtility $path, Vault $database, Singleton $config)
    {
        $this->path = $path;
        $this->database = $database;
        $this->config = $config;
    }

    /**
     * @param Request $request
     * @param Response $response
     * @method GET
     * @return Response
     */
    public function install(Request $request, Response $response){
        //for now, we return the install options so any system interacting with this can make a choice.
        $options = (object)[
            'installOptions' => (object)[
                'automatic',
            ]
        ];
        //@todo add function to allow for additional install options to be added.
        return System::asJson($response, $options);
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     * @method GET
     */
    public function list(Request $request, Response $response){
        //list all modules and their install states
        return System::asJson($response, $list);
    }

    /**
     * @param Request $request
     * @param Response $response
     * @throws \Exception
     * @method POST
     * Automatic install method. Runs the core IO installation process, requires Database user and pass as a minimum to run.
     */
    public function automatic(Request $request, Response $response){
        //@see bodyParserController.php for parsed Json.
        $body = $request->getParsedBody();
        //protect install with a key
        if(!isset($this->config->app->install->key) || empty($this->config->app->install->key)){
            throw new \Exception("There is no configuration Key set in config :: 'app->install->key' Is missing.");
        }

        if(isset($body->installKey) && $body->installKey == $this->config->app->install->key){
            //check if we have the username / pass for the database already. if we do, skip the update of the config.
            $this->setupConfig($body);
            //Next we need to check if the database exists, if not then we need to create it, or throw an error.

        } else {
            throw new \Exception("The provided Installation key || ".isset($body->installKey) ? $body->installKey : 'Unknown Key'. " || does not match expected key.");
        }
    }

    protected function setupConfig($body){
        if(isset($body->databases)) {
            foreach ($body->databases as $key => $values) {
                //first check for config.
                $host = $this->config->vault->databases->$key->dbhost ?? $body->databases->$key->host;
                $port = $this->config->vault->databases->$key->port ?? $body->databases->$key->port;
                $dbname = $this->config->vault->databases->$key->dbname ?? $body->databases->$key->dbname;
                $driver = $this->config->vault->databases->$key->driver ?? $body->databases->$key->driver;
                $operator = $this->config->vault->databases->$key->operator ?? $body->databases->$key->operator;
                $user = $this->config->vault->databases->$key->dbuser ?? $body->databases->$key->user;
                $pass = $this->config->vault->databases->$key->dbpass ?? $body->databases->$key->pass;

                //next we check for any missing values and add defaults.
                $config = [
                    'dbhost' => $host ?? 'localhost',
                    'port' => $port ?? '3306',
                    'dbname' => $dbname ?? 'Io_' . $key . '_' . microtime(),
                    'driver' => $driver ?? 'mysql',
                    'operator' => $operator ?? 'pdo',
                    'dbuser' => $user ?? '',
                    'dbpass' => $pass ?? '',
                ];

                System::writeConfig('vault', ['databases' => [$key => $config]]);
            }
        }
    }

    protected function installLoadedModules(){
        //loop over modules, if they need to be installed, install them.
        $modules = System::$module->getLoadedModules();
        foreach($modules as $module){
            $this->installModule((new $module()));
        }
        //available and need an install?
    }

    protected function installModule($module){
        $schema = $module->schema();
    }
}