<?php
/**
 * Require Db base object
 */
require_once IEM_PATH . '/ext/database/db.php';

/**
 * DataBase Factory static object
 * Factory object that will encapsulate database instantiation procedure.
 *
 * @package interspire.iem.lib.iem
 */
class IEM_DBFACTORY
{
	/**
	 * Cache of available implementation
	 * @var ?Array Cache of available implementation
	 */
	private static $_cacheLists = null;

	private function __construct() {}

	/**
	 * manufacture
	 * Manufacture a concrete implementation of the Db object
	 *
	 * @param String $host The host where the database server is located
	 * @param String $user Username to login to the database server
	 * @param String $password Password to authenticate the username
	 * @param String $name Database password
	 * @param Array $options
	 *
	 * @return MySQLDb Returns a concrete implementation of the Db object
	 *
	 * @throws exception_IEM_DBFACTORY
	 */
	public static function manufacture($host = 'localhost', $user = '', $password = '', $name = '', $options = [])
	{
		require_once IEM_PATH . '/ext/database/mysql.php';

		$db = new MySQLDb();

		if (array_key_exists('charset', $options)) {
			$db->charset = $options['charset'];
		}
		if (array_key_exists('collate', $options)) {
			$db->collate = $options['collate'];
		}
		if (array_key_exists('timezone', $options)) {
			$db->timezone = $options['timezone'];
		}
		if (array_key_exists('tablePrefix', $options)) {
			$db->TablePrefix = $options['tablePrefix'];
		}
		if (array_key_exists('sql_mode', $options)) {
			$db->sql_mode = $options['sql_mode'];
		}
		if (array_key_exists('disable_foreignkeychecks', $options)) {
			$db->disable_foreignkeychecks = !empty($options['disable_foreignkeychecks']);
		}

		if (!$db->Connect($host, $user, $password, $name)) {
			throw new exception_IEM_DBFACTORY($db->GetErrorMsg());
		}

		return $db;
	}

	/**
	 * lists
	 * List all available Db implementations in the system
	 *
	 * @return array Return an array of string of the available Db implementation
	 */
	public static function lists()
	{
		if (is_null(self::$_cacheLists)) {
			$dircontents = scandir(IEM_PATH . '/ext/database/');

			$lists = [];
			foreach ($dircontents as $each) {
				if (in_array($each, ['.', '..'. 'db.php'])) {
					continue;
				}

				list($filename, $ext) = explode('.', $each);
				$lists[] = $filename;
			}

			self::$_cacheLists = $lists;
		}

		return self::$_cacheLists;
	}

	/**
	 * exists
	 * Check whether or not an implementation exists
	 *
	 * @param String $type Database type
	 * @return Bool Returns TRUE if implementation exists, FALSE otherwise
	 */
	public static function exists($type)
	{
		$type = preg_replace('~[\W]~', '_', $type);
		return (is_readable(IEM_PATH . '/ext/database/' . $type . '.php'));
	}
}


/**
 * DBFactory exception class
 * @package interspire.iem.lib.iem
 */
class exception_IEM_DBFACTORY extends Exception
{
	public const IMPLEMENTATION_DOES_NOT_EXISTS = 1;
	public const INVALID_IMPLEMENTATION = 2;
}
