<?php

namespace Khofmann\Config;

use Exception;

/**
 * Facade for application configuration
 */
class Config
{
  // Instances array to ensure singleton pattern
  private static array $instances = [];

  // Configuration arrays
  private array $app;
  private array $database;

  /**
   * Loads configurations into arrays.
   * 
   * Private since singleton pattern.
   */
  private function __construct()
  {
    $this->app = require_once __DIR__ . "/../../config/app.php";
    $this->database = require_once __DIR__ . "/../../config/database.php";
  }

  /**
   * Disallow clone
   */
  private function __clone()
  {
    throw new Exception("Cannot clone a singleton.");
  }

  /**
   * Disallow wakeup
   */
  private function __wakeup()
  {
    throw new Exception("Cannot unserialize a singleton.");
  }

  /**
   * Get the instance. Ensures singleton pattern.
   *
   * Private to ensure only facade methods can be used.
   */
  private static function getInstance(): Config
  {
    $cls = static::class;
    if (!isset(self::$instances[$cls])) {
      self::$instances[$cls] = new static();
    }

    return self::$instances[$cls];
  }

  /**
   * @return string Application base URI path
   */
  public static function getBasePath(): string
  {
    return Config::getInstance()->app["basePath"];
  }

  /**
   * @return string Application base file system path
   */
  public static function getBaseFSPath(): string
  {
    return Config::getInstance()->app["baseFSPath"];
  }

  /**
   * @return string Application storage URI path
   */
  public static function getStoragePath(): string
  {
    return Config::getInstance()->app["storagePath"];
  }

  /**
   * @return string Application storage file system path
   */
  public static function getStorageFSPath(): string
  {
    return Config::getInstance()->app["storageFSPath"];
  }

  /**
   * @return string Application base URI path
   */
  public static function getDatabase(): array
  {
    return Config::getInstance()->database;
  }

  /**
   * @return string Application base URI path
   */
  public static function getTokenExpiry(): string
  {
    return Config::getInstance()->app["tokenExpiry"];
  }

  /**
   * @return string Application base URI path
   */
  public static function getRefreshTokenExpiry(): string
  {
    return Config::getInstance()->app["refreshTokenExpiry"];
  }
}
