<?php

/**
 * SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
 * SPDX-License-Identifier: GPL-3.0-or-later
 * @author Author: Sascha Nitsch (grumpydeveloper)
 **/

 namespace Federator;

/**
 * Base class for ContentNation and Api
 * @author Sascha Nitsch
 */
class Main
{
    /** @var Cache\Cache cache instance */
    protected $cache;
    /** @var array<string,mixed> current config */
    protected $config;
    /** @var Connector\Connector remote connector */
    protected $connector = null;
    /** @var string response content type */
    protected $contentType = "text/html";
    /** @var \Mysqli database instance */
    protected $dbh;
    /** @var array<string,string> extra headers */
    protected $headers = [];
    /** @var \Language languange instance */
    protected $lang = null;
    /** @var ?string redirect URL */
    protected $redirect = null;
    /** @var int response code */
    protected $responseCode = 200;
    /** @var \Smarty\Smarty|null smarty instance */
    protected $smarty;

    /**
     * constructor
     */
    public function __construct()
    {
        $this->config = parse_ini_file('../config.ini', true);
    }

    /**
     * do a remote call and return results
     * @param string $remoteURL remote URL
     * @param string[]|null $headers optional headers to send
     * @return array{string, mixed} response and status information
     */
    public static function getFromRemote(string $remoteURL, $headers)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $remoteURL);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if ($headers !== null) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        $ret = curl_exec($ch);
        $info = curl_getinfo($ch);
        curl_close($ch);
        return [$ret, $info];
    }

    /**
     * get config
     * @return Array<String, Mixed>
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * load plugins
     */
    public function loadPlugins() : void
    {
        if (array_key_exists('plugins', $this->config)) {
            $plugins = $this->config['plugins'];
            foreach ($plugins as $name => $file) {
                require_once($file);
                $fktn = 'Federator\\' . $name . '_load';
                if (function_exists($fktn)) {
                    $fktn($this);
                }
            }
        }
    }

    /**
     * open database
     */
    public function openDatabase() : void
    {
        $dbconf = $this->config["database"];
        $this->dbh = new \mysqli($dbconf['host'], $dbconf['username'], $dbconf['password'], $dbconf['database']);
        if ($this->dbh->connect_error !== null) {
            http_response_code(500);
            die('Database Connect Error');
        }
    }

    /**
     * set cache
     */
    public function setCache(Cache\Cache $cache) : void
    {
        $this->cache = $cache;
    }

    /**
     * set connector
     */
    public function setConnector(Connector\Connector $connector) : void
    {
        $this->connector = $connector;
    }

    /**
     * set response code
     *
     * @param int $code
     *          new response code
     */
    public function setResponseCode(int $code) : void
    {
        $this->responseCode = $code;
    }

    /**
     * translate given group and key using given language
     *
     * @param ?string $lang
     *          language to use
     * @param string $group
     *          language group to use
     * @param string $key
     *          language key to use
     * @param mixed[] $parameters
     *          optional parameters
     * @return string translation
     */
    public function translate(?string $lang, string $group, string $key, array $parameters = array()) : string
    {
        if ($this->lang === null) {
            $this->validLanguage($lang);
        }
        if ($this->lang !== null) {
            if ($this->lang->getLang() !== $lang) {
                $l = new \Language($lang);
                return $l->printlang($group, $key, $parameters);
            }
            return $this->lang->printlang($group, $key, $parameters);
        } else {
            return $key;
        }
    }

    /**
     * check if language is valid by loading it
     *
     * @param ?string $lang
     */
    public function validLanguage(?string $lang) : bool
    {
        $language = new \Language($lang);
        if ($language->getLang() === $lang) {
            $this->lang = $language;
            return true;
        }
        return false;
    }
}