<?php

namespace Snaju\Inception\Settings;

/**
 * The Config generates a list of key/value pairs for use across the application.
 * The key/values is based on the /config directory. The system uses dot syntax
 * to organize values with a namespace of the file name and a key of the array key.
 * For example if /config/database returns ['port' => 1234], this value can be retrieved
 * as "database.port"
 *
 * @package Snaju\Inception\Settings
 */
class Config
{
    /**
     * The parent directory all config files are stored at.
     *
     * @var string
     */
    private static string $directory = 'config';

    /**
     * The config object that holds all key/value pairs.
     *
     * @var array
     */
    private static array $config = array();

    /**
     * @param string $appRoot
     */
    public static function init($appRoot = __DIR__)
    {
        $baseDir = $appRoot . "/" . self::$directory;

        if (! is_dir($baseDir)) {
            return;
        }

        // Read files in the config directory, group by filename, save to config array
        $configFiles = scandir($baseDir);
        $regex = '/([A-Za-z]+)(\.php)/i';

        foreach ($configFiles as $file) {
            if (preg_match($regex, trim($file))) {
                $key = explode('.', $file);
                self::$config[$key[0]] = include $baseDir . "/" . $file;
            }
        }
    }

    /**
     * Returns a saved config value based on the 'filename.key' keyGroup.
     *
     * @param string $keyGroup
     * @return mixed|null
     */
    public static function get(string $keyGroup)
    {
        $regex = '/^[A-Za-z].+\.[A-Za-z]+$/i'; // filename.key

        if (preg_match($regex, trim($keyGroup))) {
            $keys = explode('.', $keyGroup);

            // First check if file exists, then check if property exists in array return from file
            if (array_key_exists($keys[0], self::$config)) {
                if (array_key_exists($keys[1], self::$config[$keys[0]])) {
                    return self::$config[$keys[0]][$keys[1]];
                }
            }
        }

        return null;
    }

    /**
     * Alias of `all` method.
     *
     * @see Config::all()
     * @return array
     */
    public static function getAll(): array
    {
        return self::all();
    }

    /**
     * Returns the entire saved config array.
     *
     * @return array
     */
    public static function all(): array
    {
        return self::$config;
    }

    /**
     * Convenience method to check if a file exists.
     *
     * @param string $fileName
     * @return bool
     */
    public static function fileExists(string $fileName): bool
    {
        return !! array_key_exists(
            str_replace('.php', '', $fileName),
            self::$config
        );
    }

}