<?php
###############################################################################
# Config.php
#
#
# @author Anil Kumar <akumar@codepunch.com>
# @link   https://codepunch.com
#
############################################################################### 

namespace 	CodePunch\Config;

use 		CodePunch\Base\Util as UTIL;

###############################################################################

class Config extends ConfigBase {
	
	private $db_config_database			= null;
	private $db_config_username			= null;
	private $db_config_password			= null;
	private $db_config_host				= null;
	private $db_config_driver			= null;
	private $db_config_table_prefix		= null;
	private $db_config_port				= null;
	
	private $db_config_setup_name		= null;
	private $db_config_setup_password	= null;
	
	private $db_config_publickey		= null;
	
	private $server_id					= null;
	
	private $start_time					= null;
	
	###########################################################################
	
	private $FIRSTKEY	= 'PbD6mEcik3Jq7Ed3wDukwAe+6FoYPqGfbvQa8LouISI=';
	
	###########################################################################
	
	public function __construct($defaultcfg="", $dbaction=\CodePunch\DB\Database::READONLY_TABLES) 
	{
		$this->start_time = microtime(true);
		$this->load($defaultcfg);
		$db = new \CodePunch\DB\DomainDB($this->getDBALConnectionParams(), $this->getDatabaseTablePrefix(), $dbaction);
		$this->setDatabase($db);
	}
	
	###########################################################################
	
	public function getStartTime() {
		return $this->start_time;
	}
	
	###########################################################################
	
	public function getElapsedTime() {
		return microtime(true)-$this->getStartTime();
	}
	
	###########################################################################
	
	public function isSetupUser($username) {
		if($username != "" && $username == $this->db_config_setup_name)
			return true;
		return false;
	}
	
	###########################################################################
	
	public function load($defaultcfg="") {
		$cfginfo = $this->loadcfg($defaultcfg);
		$this->db_config_database 		= $cfginfo['dbname'];
		$this->db_config_username 		= $cfginfo['user'];
		$this->db_config_password 		= $cfginfo['password'];
		$this->db_config_host 	  		= $cfginfo['host'];
		$this->db_config_driver   		= $cfginfo['driver'];
		$this->db_config_table_prefix	= $cfginfo['prefix'];
		$this->db_config_publickey		= $cfginfo['key'];
		$this->db_config_setup_name		= $cfginfo['setupuser'];
		$this->db_config_setup_password	= $cfginfo['setuppass'];
		$this->server_id 				= $cfginfo['serverid'];
		if(isset($cfginfo['port']))
			$this->db_config_port = $cfginfo['port'];
	}
	
	###########################################################################
	
	public function hasSetupAdminUser()
	{
		if($this->db_config_setup_name != "" && strlen($this->db_config_setup_password) >= 8)
			return true;
		return false;
	}
	
	###########################################################################
	
	public function checkDefaultLogin($name, $password) {
		if($name != "" && strlen($password) >= 8 && $name == $this->db_config_setup_name && $password == $this->db_config_setup_password) 
			return true;
		return false;
	}
	
	###########################################################################
	
	public function getServerID()
	{
		if($this->server_id == null || $this->server_id == "")
			return strtolower(php_uname('n'));
		else
			return $this->server_id;
	}
	
	###########################################################################
	
	public function getDatabaseTablePrefix() {
		return $this->db_config_table_prefix;
	}
	
	###########################################################################
	
	public function getDBALConnectionParams() {
		$p = array (
				'dbname' => $this->db_config_database,
				'user' => $this->db_config_username,
				'password' => $this->db_config_password,
				'host' => $this->db_config_host,
				'driver' => $this->db_config_driver
		);
		if($this->db_config_port) 
			$p['port'] = $this->db_config_port;
		return $p;
	}
	
	###########################################################################
	// This encryption is purely to protect sensitive information like   
	// passwords and API keys should a database dump be made public.
	// The keys used for this encryption are unique to each installation.
	// The data will not be safe if someone has full access to the server
	// that has this code. 
	
	public function encrypt($data)
	{
		$first_key = base64_decode($this->FIRSTKEY);
		$second_key = base64_decode($this->db_config_publickey);
			
		$method = "aes-256-cbc";    
		$iv_length = openssl_cipher_iv_length($method);
		$iv = openssl_random_pseudo_bytes($iv_length);
				
		$first_encrypted = openssl_encrypt($data,$method,$first_key, OPENSSL_RAW_DATA ,$iv);    
		$second_encrypted = hash_hmac('sha3-512', $first_encrypted, $second_key, TRUE);
		
		$output = base64_encode($iv.$second_encrypted.$first_encrypted);    
		return $output;        
	}
	
	###########################################################################
	
	public function decrypt($input)
	{
		$first_key = base64_decode($this->FIRSTKEY);
		$second_key = base64_decode($this->db_config_publickey);        
		$mix = base64_decode($input);
				
		$method = "aes-256-cbc";    
		$iv_length = openssl_cipher_iv_length($method);
					
		$iv = substr($mix,0,$iv_length);
		$second_encrypted = substr($mix,$iv_length,64);
		$first_encrypted = substr($mix,$iv_length+64);
					
		$data = @openssl_decrypt($first_encrypted,$method,$first_key,OPENSSL_RAW_DATA,$iv);
		$second_encrypted_new = hash_hmac('sha3-512', $first_encrypted, $second_key, TRUE);
			
		if($second_encrypted_new !== false && $second_encrypted !== false) {
			if (hash_equals($second_encrypted,$second_encrypted_new))
				return $data;
		}
			
		return false;
	}
	
	###############################################################################
	
	public function getApplicationStatus()
	{
		$vi = array('update'=>0);
		$vi['version'] = \CodePunch\Config\Defaults::version_and_build();
		$vi['buildno'] = \CodePunch\Config\Defaults::BUILD_INDEX;
		$vi['product'] = \CodePunch\Config\Defaults::product();
		$vi['license'] = $this->getLicense();
		$vi['download'] = $this->getDownloadURL("zip");

		$vd = UTIL::curl_get_url($this->getDownloadURL("ver"), 20);
		if($vd['status'] == 200) {
			$verdata = json_decode($vd['result'], true);
			if(isset($verdata['date'])) {
				$thatbuild = $verdata['date'];
				$vi['available'] = $thatbuild;
				if(strlen($thatbuild) == 6) {
					$latest = mktime(0,0,0,
						intval(substr($thatbuild, 0, 2)),
						intval(substr($thatbuild, 2, 2)),
						intval(substr($thatbuild, 4, 2)) + 2000);
					$current = strtotime(\CodePunch\Config\Defaults::BUILD_DATE);
					$vi['available'] = date("Y-M-d", $latest);
					$vi['current'] = date("Y-M-d", $current);
					if($latest > $current) {
						$vi['update'] = 1;
					}
					$m1 = $verdata['majorversion'];
					$m2 = $verdata['minorversion'];
					$newver = $m1/100 . "." . $m2/100;
					$vi['newversion'] = $newver . "." . $verdata['buildindex'] . ", " . date("M d Y", $latest);
				}
			}
		}
		else {
			if(isset($vd['error']))
				$vi['error'] = $vd['error'];
		}
		return $vi;
	}
	
	###############################################################################

	public static function ioncube_loader_version_array () 
	{
		// ioncube_loader_iversion is the newer function, use it if it is available.
		if ( function_exists('ioncube_loader_iversion') ) {
			$ioncube_loader_iversion = ioncube_loader_iversion();
			if($ioncube_loader_iversion >= 100000) {
				// MMmmrr
				$ioncube_loader_version_major = (int)substr($ioncube_loader_iversion,0,2);
				$ioncube_loader_version_minor = (int)substr($ioncube_loader_iversion,2,2);
				$ioncube_loader_version_revision = (int)substr($ioncube_loader_iversion,4,2);
				$ioncube_loader_version = "$ioncube_loader_version_major.$ioncube_loader_version_minor.$ioncube_loader_version_revision";
			}
			else {
				// Mmmrr
				$ioncube_loader_version_major = (int)substr($ioncube_loader_iversion,0,1);
				$ioncube_loader_version_minor = (int)substr($ioncube_loader_iversion,1,2);
				$ioncube_loader_version_revision = (int)substr($ioncube_loader_iversion,3,2);
				$ioncube_loader_version = "$ioncube_loader_version_major.$ioncube_loader_version_minor.$ioncube_loader_version_revision";
			}
		} 
		else {
			$ioncube_loader_version = ioncube_loader_version();
			$ioncube_loader_version_major = (int)substr($ioncube_loader_version,0,1);
			$ioncube_loader_version_minor = (int)substr($ioncube_loader_version,2,1);
		}
		return array('version'=>$ioncube_loader_version, 'major'=>$ioncube_loader_version_major, 'minor'=>$ioncube_loader_version_minor);
	}
		
	###########################################################################
}
