<?php
namespace apexl\Io\includes;

use apexl\Config\Singleton;
use apexl\Io\interfaces\IoModuleInterface;
use apexl\Vault\Vault;
use DI\Bridge\Slim\Bridge;

abstract class Module implements IoModuleInterface{

    /** @var Bridge */
    protected $Io;
    protected $path;
    /** @var Singleton */
    protected $config;
    /** @var Routes */
    protected $route;
    /** @var Vault */
    protected $database;

    public function __construct(){}

    public function initialise(Singleton $config, Vault $database){
        $this->Io = System::$app;
        $this->config = $config;
        $this->database = $database;
        $this->route = new Routes();
    }

    public function requiresInstall(){
        return !empty($this->schema());
    }
    public function routes (){}

    /**
     * @return mixed
     */
    public function schema (){
        return (object)[];
    }
    public function install (){
        return !$this->requiresInstall();
    }

    public function getName(){
        $folders = explode(PATH_SEPARATOR, __DIR__);
        return end($folders);
    }

    public function getNameFromNamespace($namespace){
        $moduleSpaces = explode('\\', $namespace);
        return str_replace('Module', '', array_pop($moduleSpaces));
    }

    public function uninstall(){

    }

    public function markInstalled($namespace){
        //update the installation status.
        $vault = Vault::getInstance();
        if($this->checkExistsInDB($namespace)){
            $vault->update('modules')->fields(['installed' => 1])->where('namespace', '\\' . $namespace)->execute();
        } else {
            $vault->insert('modules')->fields(
                [
                    'name' => $this->getNameFromNamespace($namespace),
                    'namespace' => '\\'.$namespace,
                    'weight' => 1,
                    'installed' => 1,
                    'lastInstallDate' => time()
                ]
            )->execute();
        }
    }

    protected function checkExistsInDB($namespace){
        //we need to check if we know about this module. If we dont then this is an insert.
        //update the installation status.
        $vault = Vault::getInstance();
        $module = $vault->select('modules')->fields()->where('namespace', '\\'.$namespace)->execute()->fetchAssoc();
        return !empty($module);
    }
}