<?php
namespace SabaiApps\Framework\DB;

use SabaiApps\Framework\Exception;

/**
 * MySQLConnection class for managing connections to a MySQL database using the MySQLi extension.
 * Handles connection setup, client encoding, and SSL options.
 */
class MySQLConnection extends AbstractConnection {

	/**
	 * @var string
	 */
	protected $_resourceHost;
	/**
	 * @var string
	 */
	protected $_resourcePort;
	/**
	 * @var string
	 */
	protected $_resourceName;
	/**
	 * @var string
	 */
	protected $_resourceUser;
	/**
	 * @var string
	 */
	protected $_resourceUserPassword;
	/**
	 * @var bool
	 */
	protected $_resourceSecure;
	/**
	 * @var resource
	 */
	protected $_link;
	/**
	 * @var string
	 */
	protected $_clientFlags;
	/**
	 * @var string
	 */
	protected $_charset = 'utf8';

	/**
	 * @var array
	 */
	protected static $_charsets = array(
		'utf-8'        => 'utf8',
		'big5'         => 'big5',
		'cp-866'       => 'cp866',
		'euc-jp'       => 'ujis',
		'euc-kr'       => 'euckr',
		'gb2312'       => 'gb2312',
		'gbk'          => 'gbk',
		'iso-8859-1'   => 'latin1',
		'iso-8859-2'   => 'latin2',
		'iso-8859-7'   => 'greek',
		'iso-8859-8'   => 'hebrew',
		'iso-8859-8-i' => 'hebrew',
		'iso-8859-9'   => 'latin5',
		'iso-8859-13'  => 'latin7',
		'iso-8859-15'  => 'latin1',
		'koi8-r'       => 'koi8r',
		'shift_jis'    => 'sjis',
		'tis-620'      => 'tis620',
	);

	/**
	 * Constructor
	 */
	public function __construct( array $config ) {
		parent::__construct( 'MySQL' );
		$this->_resourceName         = $config['dbname'];
		$this->_resourceHost         = $config['host'];
		$this->_resourcePort         = ! empty( $config['port'] ) ? $config['port'] : 3306;
		$this->_resourceUser         = $config['user'];
		$this->_resourceUserPassword = $config['pass'];
		$this->_resourceSecure       = ! empty( $config['secure'] );
		if ( isset( $config['charset'] ) ) {
			$charset        = strtolower( $config['charset'] );
			$this->_charset = isset( self::$_charsets[ $charset ] ) ? self::$_charsets[ $charset ] : $charset;
		}
	}

	/**
	 * Establishes a connection to the MySQL database.
	 *
	 * @throws Exception If the connection fails.
	 */
	protected function _doConnect() {
		$this->_clientFlags = $this->_resourceSecure ? MYSQLI_CLIENT_FOUND_ROWS | MYSQLI_CLIENT_SSL : MYSQLI_CLIENT_FOUND_ROWS;
		$link               = mysqli_init();
		if ( ! mysqli_real_connect(
			$link,
			$this->_resourceHost,
			$this->_resourceUser,
			$this->_resourceUserPassword,
			$this->_resourceName,
			$this->_resourcePort,
			null,
			$this->_clientFlags
		) ) {
			throw new Exception( sprintf( 'Unable to connect to database server. Error: %s(%s)', mysqli_connect_error(), mysqli_connect_errno() ) );
		}
		mysqli_autocommit( $link, true );

		// Set client encoding if requested
		if ( ! empty( $this->_charset ) ) {
			mysqli_set_charset( $link, $this->_charset );
		}

		$this->_link = $link;
	}

	/**
	 * Gets the MySQL connection resource.
	 *
	 * @return resource MySQL connection resource.
	 */
	public function getLink() {
		return $this->_link;
	}

	/**
	 * Gets the charset used for the connection.
	 *
	 * @return string Charset name.
	 */
	public function getCharset() {
		return $this->_charset;
	}
}
