<?php

declare(strict_types=1);

namespace netico\Bones;

/**
 * The Configuration class retrieves configuration variables from an .ini file.
 *
 * It requires the path to the configuration file.
 * As for security, keeping the configuration file out of the web root is the first step.
 * Making it read-only and restricting access may make it more secure.
 * The .ini files have a trivial syntax so they are easy to edit and understand.
 * Also it is the syntax of PHP configuration files.
 *
 *      [application]
 *      name=foo
 *
 *      [template]
 *      name=bar
 *
 *      [sqlite]
 *      database=/path/to/file.sqlite
 *
 * And then:
 *
 *      $c = new \netico\Bones\Configuration();
 *      $name = $c->getValue('application', 'name');
 *      print $name;
 *
 * @package bones
 * @link https://git.lattuga.net/netico/code-library/src/master/Framework
 * @copyright Copyright (c) 2016, 2022 netico <netico@riseup.net>
 * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License
 * @author netico <netico@riseup.net>
 *
 */
class Configuration
{
    /**
     * @var string[] $config Array of string objects. It represents the content of the INI file.
     */
    private $config;

    /**
     * This code works if you set the CONFIG constant.
     * @return void
     */
    public function __construct()
    {
        $this->config = $this->parser(CONFIG);
    }

    /**
     * parser
     *
     * @param string $filename path of INI config file.
     * @return string[] An array of string objects.
     */
    private function parser($filename)
    {
        if (is_readable($filename)) {
            $res = array();
            $section = "";
            $fdo = fopen($filename, "r");
            while (feof($fdo) != true) {
                $fc = fgets($fdo, 4096);
                if ($fc != false) {
                    $line = trim($fc);
                    $len = strlen($line);
                    if ($len != 0 && $line[0] != ';' && $line[0] === '[' && $line[$len - 1] === ']') {
                        $section = substr($line, 1, $len - 2);
                    }
                    $pos = strpos($line, '=');
                    if ($pos > 0 && $section != "") {
                        $name = trim(substr($line, 0, $pos));
                        $value = trim(substr($line, $pos + 1, $len - $pos - 1));
                        $value = str_replace('"', '\\"', $value);
                        $value = str_replace("\"", '\\\'', $value);
                        $res["$section"]["$name"] = $value;
                    }
                }
            }
            fclose($fdo);
        }
        return $res;
    }

    /**
     * This method gets a configuration option.
     *
     * @param string $section Section in INI file (for example: '[section]').
     * @param string $name Key in file INI (for example: 'key=').
     * @return string Value (for example: '=value').
     */
    public function getValue($section, $name)
    {
        foreach ($this->config as $i => $a) {
            $b = array();
            $b = (array) $a;
            foreach ($b as $n => $v) {
                if (strcmp($i, $section) == 0 && strcmp($n, $name) == 0) {
                    return (string) $v;
                }
            }
        }
        return (string) 'Undefined';
    }
}
