<?php
/**
* CMSMSExt config class
* A convenience class to centralize
* all Config values in one ArrayAccess type object
*
* @author Jo Morg (Fernando Morgado)
* @version 1.0
*/
namespace CMSMSExt;

/**
 * Class config
 *
 * @package CMSMSExt
 */
class config implements \ArrayAccess
{
  
  /**
  * @access private
  */
  private static $_data = [];
  
  /**
  * The instance
  * @access private
  */
  private static $_instance;
  
  /**
  * CMSMS own config
  * @access private
  */
  private static $_CMSMS_CFG;
  
  /**
  * Private constructor to prevent it being created directly
  * @access private
  */
  private function __construct(){}
  
  /**
  * GetInstance method used to access the object
  * @access public
  * @return
  */
  public static function GetInstance()
  {
    if( !isset(self::$_instance) )
    {
      self::$_instance = new self;
      self::$_CMSMS_CFG = \cmsms()->GetConfig();
      $module_path = dirname(__FILE__, 2);
      $file = cms_join_path($module_path, 'data', 'cfg.inc');
      $cfg = [];
      
      if( \file_exists($file) )
      {
        include($file);
        self::$_data = $cfg ?? [];
      }
      
      self::$_data['module_path'] = $module_path;
    }
    
    return self::$_instance;
  }
  
  /**
   * @param $key
   *
   * @return bool
   */
  private static function exists($key) : bool
  {
    return ( isset(self::$_data[$key]) || self::$_CMSMS_CFG->offsetExists($key) );
  }
  
  /**
  * prevent cloning of the object: issues an E_USER_ERROR if this is attempted
  */
  public function __clone()
  {
    throw new \RuntimeException('Cloning the Config is not permitted');
  }
  
  /**
   * Get a data by key
   *
   * @param string The key data to retrieve
   *
   * @access public
   * @return mixed
   */
  public function &__get ($key)
  {
    if(self::$_CMSMS_CFG->offsetExists($key))
    {
      return self::$_CMSMS_CFG[$key];
    }
    
    return self::$_data[$key];
  }
  
  /**
   * Assigns a value to the specified data
   *
   * @param string The data key to assign the value to
   * @param mixed  The value to set
   *
   * @access public
   * @throws \RuntimeException
   */
  public function __set($key, $value)
  {
    throw new \RuntimeException('Read Only');
  }
  
  /**
   * @param string $name
   *
   * @return bool
   */
  public function __isset($key)
  {
    return ( isset(self::$_data[$key]) || self::$_CMSMS_CFG->offsetExists($key) );
  }
  
  
  /**
   * @param mixed $key
   *
   * @return bool
   */
  #[\ReturnTypeWillChange]
  public function offsetExists($key)
  {
    return ( isset(self::$_data[$key]) || self::$_CMSMS_CFG->offsetExists($key) );
  }
  
  /**
   * @param mixed $key
   *
   * @return mixed|null
   */
  #[\ReturnTypeWillChange]
  public function offsetGet($key)
   {
     if(self::$_CMSMS_CFG->offsetExists($key)) { return self::$_CMSMS_CFG[$key]; }
  
     return self::$_data[$key] ?? NULL;
   }
  
  /**
   * @param mixed $key
   * @param mixed $value
   *
   * @throws \RuntimeException
   */
  #[\ReturnTypeWillChange]
  public function offsetSet($key, $value)
   {
     throw new \RuntimeException('Read Only');
   }
  
  /**
   * @param mixed $key
   *
   * @throws \RuntimeException
   */
  #[\ReturnTypeWillChange]
  public function offsetUnset($key)
   {
     throw new \RuntimeException('Read Only');
   }
  
  /**
   * @param $key
   *
   * @return mixed
   */
  public static function get($key)
  {
    if(self::$_CMSMS_CFG->offsetExists($key)) return self::$_CMSMS_CFG[$key];
    
    if( self::exists($key) )
    {
      return self::$_data[$key];
    }
  }
  
  /**
   * @param $key
   * @param $value
   */
  public static function set($key, $value)
  {
    throw new \RuntimeException('Read Only');
  }
  
  /**
   * @param $key
   */
  public static function erase($key)
  {
    throw new \RuntimeException('Read Only');
  }
}
?>