<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
#[\AllowDynamicProperties]
class Setup extends MY_Controller {

	// PHP Version
	private $version = '5.6.0';

	private $isDependent = 0;

	private $env_php = '';

	private $lock_file = '';

	private $installer_dir = '';

	private $database_file = '';

	private $message = '';

	private $dbConn	= null;

	private $is_exe	= 0;

	private $licFile = "";

	private $download_url	= 'https://www.outputbooks.com/release/index.php';

	private $extensions_needed	= array(
		'zlib'	=> array(
			'name'	=> 'zlib',
			'value'	=> false,
			'label'	=> 'Zlib Compression plugin (zlib)'
		),
		'zip'	=> array(
			'name'	=> 'zip',
			'value'	=> false,
			'label'	=> 'Zip Compression plugin (zip)'
		),
		'xml'	=> array(
			'name'	=> 'xml',
			'value'	=> false,
			'label'	=> 'XML plugin (xml)'
		),
/*		'mysql'	=> array(
			'name'	=> 'mysql',
			'value'	=> false,
			'label'	=> 'MySql plugin (mysql)'
		),
*/ 		'mysqli'	=> array(
 			'name'	=> 'mysqli',
 			'value'	=> false,
 			'label'	=> 'MySqli plugin (mysqli)'
 		),
		'json'	=> array(
			'name'	=> 'json',
			'value'	=> false,
			'label'	=> 'JSON plugin (json)'
		),
		'curl'	=> array(
			'name'	=> 'curl',
			'value'	=> false,
			'label'	=> 'CURL plugin (curl)'
		),
		'sockets'	=> array(
			'name'	=> 'sockets',
			'value'	=> false,
			'label'	=> 'PHP Socket (sockets)'
		)/*
		,
		'otime'	=> array(
			'name'	=> 'otime',
			'value'	=> false,
			'label'	=> 'OutputBooks plugin (otime)',
			'path'	=> 'http://www.outputbooks.com/installer/'
		),
*/
// 		array(
// 			'name'	=> 'gd',
// 			'value'	=> false,
// 			'label'	=> 'GD Library'
// 		),
	);

	private $installed	= false;

	function __construct()
	{
/*
		if (defined('SHARED_HOST'))
		{
			unset($this->extensions_needed["otime"]);
		}
*/

		$this->env_php	= FCPATH . 'env.php';
		$this->lock_file	= FCPATH . 'temp/setup.lock';
		$this->database_file	= FCPATH . 'database/outputbooks.sql';
		$this->installer_dir	= FCPATH . 'installer';

		parent::__construct();

		if ($this->is_locked())
		{
			return false;
		}

		if ($this->is_already_installed())
		{
			$this->installed = true;
			return false;
		}

		$this->licFile = $this->_load_license_key_file();

		$this->is_exe = !empty($_SERVER['OutputApp']) ? 1 : 0;
	}

	public function index()
	{
		$data	= array();
		$data['is_exe']		= $this->is_exe;
		
		$data['installed']	= false;
		$data['isDependent']	= false;
		$data['is_windows']	= PHP_OS == "WINNT" ? true : false;

		$data['comptype'] = json_decode(file_get_contents(FCPATH . "/common/third_party/comptype.json"), true);

		if ($this->installed)
		{
			$data['installed']	= true;
			$this->load->view('setup/index', $data);
			return true;
		}

		// PHP Version >= 5.3.1
		// config folder Writable

		$data['extensions']	= $this->check_extensions();
		
		$data['php_version']	= array(
			'name'	=> 'version',
			'value'	=> false,
			'label'	=> 'PHP Version ' . PHP_VERSION . ' >= ' . $this->version
		);
		
		if (version_compare(PHP_VERSION, $this->version) >= 0)
		{
			$this->isDependent++;
			$data['php_version']['value']	= true;
		}

		$data['config']	= array(
			'name'	=> 'config',
			'value'	=> false,
			'label'	=> '<strong>env.php</strong> file Writable'
		);

		if (is_writable($this->env_php))
		{
			$this->isDependent++;
			$data['config']['value'] = true;
		}

		$data['isDependent'] = ($this->isDependent == (count($data['extensions']) + 2)) ? false : true;

		$url = site_url('setup/extensions');
/*
		if (!defined('SHARED_HOST'))
		{
			$data['extensions']['otime']['url']	= $url;
			$data['extensions']['otime']['dislay_file_name'] = (PHP_SHLIB_SUFFIX === "dll" ? "php_otime." : "otime.") . PHP_SHLIB_SUFFIX;
		}
*/
		if ($dbconfig = $this->can_connect_db())
		{
			$data['dbconfig'] = $dbconfig;

			if ($this->dbConn && !$this->is_db_empty())
			{
				$step = $this->is_exe ? 3 : 5;

				$data['countries'] = $this->countries();
				$data['companies'] = $this->companies();

				if (!empty($data['countries']))
				{
					$step++;
				}

				$data['step'] = $step;
			}
		}

		$data["licFile"] = $this->licFile;

		$this->load->view('setup/index', $data);

		return true;
	}

	private function is_already_installed()
	{
		if (file_exists($this->env_php))
		{
			include($this->env_php);
			if (isset($installed) && $installed)
			{
				return true;
			}

			if ($dbconfig = $this->can_connect_db())
			{
				if ($this->dbConn && !$this->is_db_empty())
				{
					$compsettings = $this->compsettings();
					if (count($compsettings))
					{
						$this->installed();
						redirect(site_url(""));
						return true;
					}
				}
			}

			return false;
		}

		$this->create_env_file();

		return false;
	}

	private function _load_license_key_file()
	{
		$licFile = FCPATH . "OutputBooks.lic";
		if (!file_exists($licFile))
		{
			return false;
		}

		$licFile = json_decode(trim(file_get_contents($licFile)), true);

		if (empty($licFile["licenseKey"]))
		{
			return false;
		}

		$lic_data = $this->decrypt($licFile["licenseKey"]);

		if (!$lic_data)
		{
			return false;
		}

		return $licFile;
/*
		if (!empty($lic_data['data']) && !empty($lic_data['data']['comp']))
		{
			$lic_data['data']['comp'] = array_values($lic_data['data']['comp']);
		}
		$this->license_detail = $lic_data;
*/
	}

	private function create_env_file()
	{
		$content = "";
		$content .= "<?php" . PHP_EOL . PHP_EOL;
		$content .= "// production, development, testing" . PHP_EOL;
		$content .= "\$env='production';" . PHP_EOL . PHP_EOL;
		$content .= "\$env_database=array();" . PHP_EOL;
		$content .= "\$env_database['hostname']='##HOST_NAME##';" . PHP_EOL;
		$content .= "\$env_database['username']='##USER_NAME##';" . PHP_EOL;
		$content .= "\$env_database['password']='##PASSWORD##';" . PHP_EOL;
		$content .= "\$env_database['database']='##DB_NAME##';" . PHP_EOL;
		$content .= "\$installed=false;" . PHP_EOL;
		file_put_contents($this->env_php, $content);
	}

	private function check_extensions()
	{
		$arr = $this->extensions_needed;
		foreach($arr as $key=>$val)
		{
			if (extension_loaded($val['name']))
			{
				$arr[$key]['value']	= true;
				$this->isDependent++;
			}
		}

		return $arr;
	}

	private function can_connect_db()
	{
		if (file_exists($this->env_php))
		{
			require($this->env_php);
			if (!empty($env_database))
			{
				if ($env_database['hostname'] == '##HOST_NAME##')
				{
					return false;
				}

				$env_database['dbdriver'] = "mysqli";
				$env_database['dbprefix'] = "ob_";
				$env_database['pconnect'] = false;

				$result	= $this->is_db_exists($env_database);
				if (!empty($result))
				{
					return $env_database;
				}
			}

			return false;
		}

		return false;
	}

	private function is_db_exists($config=array())
	{
// 		$config['hostname'] = "localhost";
// 		$config['username'] = "myusername";
// 		$config['password'] = "mypassword";
// 		$config['database'] = "mydatabase";
// 		$config['dbdriver'] = "mysqli";
// 		$config['dbprefix'] = "ob_";
// 		$config['pconnect'] = false;
		$config['db_debug'] = false;

		// check db exists
        $tmp_config = $config;
        $db_name = $tmp_config['database'];
        $tmp_config['database'] = '';

        $this->load->database($tmp_config, false, true);

        $query = $this->db->query(
            "SELECT SCHEMA_NAME 
            FROM INFORMATION_SCHEMA.SCHEMATA 
            WHERE SCHEMA_NAME = ?",
            array($db_name)
        );

        if ($query->num_rows() == 0) {
            $this->message	= '"'.$db_name.'" database not exist.';
            return false;
        }

		$this->dbConn = @$this->load->database($config, true);

		if (!$this->dbConn->conn_id)
		{
			$this->message	= 'Couldn\'t connet to database using given settings.';
			return false;
		}

		if (!$this->dbConn->db_select())
		{
			$this->message	= 'Database not exist.';
			return false;
		}

		if (!$this->is_db_empty())
		{
			$this->message	= 'Database not empty.';
		}

		// $this->message	= 'Database exist.';
		return true;
	}

	private function init_db_conn($config=array())
	{
		if ($this->dbConn)
		{
			$this->dbConn->close();
		}
		$this->dbConn = $this->load->database(array_merge($config, array('dbprefix'=>'ob_')), true);
	}

	private function is_db_empty()
	{
		// $result = $this->dbConn->list_tables();
		$query	= $this->dbConn->query('SHOW TABLES LIKE "ob_%";');
		$result	= $query->result_array();
		if (count($result) > 0)
		{
			return false;
		}

		return true;
	}

	private function getBit()
	{
		// if not assign in variable strstr raise some error in windows.
		$arch	= strstr(php_uname("m"), '64');
		return empty($arch) ? 32 : 64;
/*
		// In windows os for 64bit php PHP_INT_SIZE will return 4 so here we check using php_uname
		if ("WINNT" == PHP_OS)
		{
			return empty(strstr(php_uname("m"), '64')) ? 32 : 64;
		}
		else
		{
			return (PHP_INT_SIZE * 8);
		}
*/
	}

	public function extensions()
	{
		$extensions_dir	= APPPATH . 'extensions/';

		$version	= explode('.', PHP_VERSION);
		$version	= $version[0] . '.' . $version[1];
		$bit		= $this->getBit();	// 32 or 64 bit
		$type		= PHP_SHLIB_SUFFIX;

		if ($type === "dll")
		{
			$file	= "php_otime_" . $version . "_" . $bit . 'bit.' . $type;
			$download_name	= "php_otime." . $type;
		}
		else
		{
			$file	= "otime_" . $version . "_" . $bit . "bit." . $type;
			$download_name	= "otime." . $type;
		}

		$this->download_file($extensions_dir . $file, $download_name, true);
	}

	private function download_file($file='', $file_name='', $isBinary=false)
	{
		if (file_exists($file))
		{
			if ($isBinary)
			{
				header("Content-type: application/octet-stream");
			}
			else
			{
				header("Content-type: application/zip");
			}
			header("Content-Disposition: attachment; filename=" . $file_name);
			header("Content-length: " . filesize($file));
			header("Pragma: no-cache");
			header("Expires: 0");
			readfile($file);
		}
		else
		{
			header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
		}
	}

	private function write_output($success=true, $message="", $data=array())
	{
// 		header("Content-type: text/json; charset=utf-8");
		header("Content-type: application/json; charset=utf-8");
		echo json_encode(array($success, $message, $data));
		exit;
	}

	private function create_lock()
	{
		@file_put_contents($this->lock_file, '1');
	}

	private function remove_lock()
	{
		@unlink($this->lock_file);
	}

	private function is_locked()
	{
		if(file_exists($this->lock_file))
		{
			return true;
		}

		return false;
	}

	public function check_license()
	{
		$data	= $_POST;

		if (!empty($data) && $data['license_key'])
		{
			$data['license_key'] = trim($data['license_key']);

			$lic_data = $this->decrypt($data['license_key']);

			if (!$lic_data)
			{
				$this->write_output(false, 'Invalid License Key.', array());
				return false;
			}
			if (!empty($lic_data['data']) && !empty($lic_data['data']['comp']))
			{
				$lic_data['data']['comp'] = array_values($lic_data['data']['comp']);
			}
			$this->write_output(true, '', array('license_detail'=>$lic_data));
			return true;
		}

		$this->write_output(false, 'License key missing.', array());
		return false;
	}

	public function activate()
	{
		$data = $_POST;
		if (empty($data) || empty($data["license_key"]))
		{
			$this->write_output(false, 'Required field missing.', array());
			return false;
		}

		$this->load->library('ob_license');

		$actKey = $this->ob_license->activate($data['license_key']);
		if ($actKey === false)
		{
			$ret = array(
				"reqKey" => $this->ob_license->reqKey,
				"actUrl" => $this->ob_license->actUrl
			);
			
			$this->write_output(false, $this->ob_license->message, $ret);
			return false;
		}

		$this->write_output(true, '', array(
			'isActive' => 1,
			'actKey' => $actKey
		));
		return true;
	}

	public function check_activation()
	{
		$data	= $_POST;
		if (empty($data) || empty($data["license_key"]) || empty($data["actKey"]))
		{
			$this->write_output(false, 'Required field missing.', array());
			return false;
		}

		$this->load->library('ob_license');
		$isActive = $this->ob_license->is_activated($data['license_key'], $data["actKey"]);

		$this->write_output(true, '', array('isActive'=>$isActive));
		return true;
	}

	private function decrypt($string="")
	{
		$this->load->library('ob_license');
		return $this->ob_license->isValidLicenseKey($string);
	}

	private function escape_str($str='')
	{
		return addslashes($str);
		// return mysqli_real_escape_string($str);
	}
	public function test_email()
	{
		$data	= $_POST;

		if (!empty($data['smtp_config']) && !empty($data['to_email']) && !empty($data['license_key']))
		{
			$lic_data	= $this->decrypt($data['license_key']);
			if (!$lic_data)
			{
				$this->write_output(false, 'Invalid License Key.', array());
				return false;
			}

			$smtp	= $data['smtp_config'];

			$config = Array (
				'protocol' => 'smtp',
				'smtp_host' => $smtp['smtp_host'],
				'smtp_port' => $smtp['smtp_port'],
				'smtp_user' => $smtp['smtp_user'],
				'smtp_pass' => $smtp['smtp_pass'],
				'charset' => "UTF-8",
				'mailtype' => 'html',
				'smtp_timeout' => 60,
				'newline'	=> "\r\n"
			);

			$this->load->library('email', $config);
			$this->email->from($smtp['smtp_user'], 'OutputBooks');
			$this->email->to($data['to_email']);
			$this->email->subject('SMTP Test Mail From OutputBooks.');
			$this->email->message(nl2br('SMTP Test Mail From OutputBooks On-Premises Server of ' . $lic_data['company_name']));

			if (!$this->email->send())
			{
				$this->write_output(false, 'Can\'t send email with this SMTP configuration.', array());
				return false;
			}

			$this->write_output(true, 'SMTP working fine.', array());
			return true;
		}

		$this->write_output(false, 'Required field missing.', array());
		return false;
	}

	public function install()
	{
		if ($this->is_locked())
		{
			$this->write_output(false, 'Already Installer running.', array());
			return;
		}

		try {
			$data	= $_POST;

			if (empty($data['db']) && file_exists($this->env_php))
			{
				include($this->env_php);
				if (isset($env_database) && $env_database)
				{
					$data['db'] = $env_database;
				}
			}

			if (empty($data['db']) || empty($data['license_key']) || empty($data['password']) || empty($data['email']))
			{
				$this->write_output(false, "Required field missing.", array());
				return false;
			}

			$data['license_key'] = trim($data['license_key']);

			$return	= false;
			$this->create_lock();

			$this->dbSettings($data['db']);

			if ($this->is_db_exists($data['db']))
			{
				$eData	= $this->decrypt($data['license_key']);

				if (!$eData)
				{
					$this->remove_lock();
					$this->write_output(false, 'Invalid License Key.', array());
					return;
				}

	/*
				if (!$eData["isTrial"])
				{
					$isActive = $this->ob_license->is_activated($data['license_key'], $data["actKey"]);
					if (!$isActive)
					{
						$this->remove_lock();
						$this->write_output(false, 'Not yet activated.', array());
						return;
					}
				}
	*/
				$eData['license_key'] = $data['license_key'];
				$eData['data']['email'] = $data['email'];
				$eData['data']['password'] = $data['password'];

				$this->update_db_config($data['db']);
				$this->init_db_conn($data['db']);

				// $this->dbConn->cache_off();

				if ($this->is_db_empty())
				{
					$this->import_database();
				}

				// $this->dbConn->cache_delete();

				$this->update_user_data($eData);
				$this->update_activation(array(
					"uId" => $eData["uId"],
					"actKey" => $data["actKey"]
				));
				$this->update_company_data($eData);
	// file_put_contents("log.txt", "dbConn : " . print_R($this->dbConn, true));
				// $this->installed();
				$this->remove_lock();
				$retData = array();
				$retData['countries'] = $this->countries();

	// Trial Activation Log begin			
				if (empty($data["actKey"]))
				{
					$this->load->library('ob_license');
					$actKey = $this->ob_license->activate($data['license_key']);
					if ($actKey === false)
					{
						// Activation Failed
					}
				}
				$this->dbConn->query("call obsptree('G');");
				$this->dbConn->query("call obsptree('C');");
	// Trial Activation Log End
				$this->write_output(true, '', $retData);
				return;
			}
		} catch (Exception $ex) {
			$this->message = $ex->getMessage();
		}

 		// $this->remove_config();
		$this->remove_lock();
		$this->write_output(false, $this->message, array());
	}

	public function companies()
	{
		return $this->dbConn->select('id, name')->from('companies')->get()->result_array();
	}

	public function compsettings()
	{
		return $this->dbConn->select('cId')->from('compsettings')->where("cId !=", "0")->get()->result_array();
	}

	public function countries()
	{
		return $this->dbConn->select('countryCode, countryName, currencyCode')->from('countries')->get()->result_array();
	}

	public function states($countryCode)
	{
		if ($this->dbConn || $this->can_connect_db())
		{
			$this->load->helper("file");
			$retData = array();
			$retData['states'] = $this->dbConn->select('id, name, stateCode')->from('states')->where("countryCode", $countryCode)->get()->result_array();

			if (empty($retData['states']))
			{
				$file = FCPATH . 'database/' . $countryCode . '.sql';
				if (is_file($file))
				{
					$queries = $this->splitSql($file);

					foreach ($queries as $key=>$val)
					{
						$val = trim($val);
						if ($val)
						{
							$this->dbConn->query($val);
						}
					}

					$retData = array();
					$retData['states'] = $this->dbConn->select('id, name, stateCode')->from('states')->where("countryCode", $countryCode)->get()->result_array();
				}
			}

			$this->write_output(true, '', $retData);
			return;
		}

		$this->write_output(false, 'DB Conenct error', array());
	}

	private function installed()
	{
		file_put_contents($this->env_php, PHP_EOL . '$installed=true;' . PHP_EOL, FILE_APPEND);
		@chmod($this->env_php, 0777);
		return true;
	}

	private function update_db_config($data=array())
	{
		$cont = file_get_contents($this->env_php);

		$cont = str_replace("##HOST_NAME##", $data['hostname'], $cont);
		$cont = str_replace("##USER_NAME##", $data['username'], $cont);
		$cont = str_replace("##PASSWORD##", $data['password'], $cont);
		$cont = str_replace("##DB_NAME##", $data['database'], $cont);

		file_put_contents($this->env_php, $cont);

		@chmod($this->env_php, 0777);

		return true;
	}

	private function update_user_data($data=array())
	{
		// Insert User
		$userData = array(
			"id" => $data["uId"],
			"email" => $data['data']['email'],
			"name" => $data['data']['email'],
			"loginName" => $data['data']['email'],
			"password" => $data['data']['password'],
			"isPrimeUser" => "1"
		);
		$userData["password"] = $this->ob_license->hash_ob_password($data['data']['email'].$data["uId"].$userData["password"]);

		$this->dbConn->insert("users", $userData);

		// Insert License Key
		$licDetails = array(
			"uId" => $data["uId"],
			"licenseKey" => trim($data["license_key"]),
			"plan" => $data["plan"],
			"createdOn" => $data["dateF"],
			"expiredOn" => $data["expiredOnF"]
		);

		$this->dbConn->insert("licensekey", $licDetails);
	}

	private function update_activation($data=array())
	{
		// Insert License Key
		$actDetails = array(
			"uId" => $data["uId"],
			"actKey" => trim($data["actKey"]),
			"info" => "" // $data["info"]
		);

		$this->dbConn->insert("activationkey", $actDetails);
	}

	private function update_company_data($data=array())
	{
		if (!empty($data['data']) && !empty($data['data']['comp']))
		{
			$companies = array();
			$compusers = array();
			foreach($data['data']['comp'] as $key => $val)
			{
				$companies[] = array(
					"id" => $key,
					"name" => $val,
					"primUserid" => $data["uId"]
				);

				$compusers[] = array(
					"userId" => $data["uId"],
					"cId" => $key,
					"roleId" => 0
				);
			}

			$this->dbConn->insert_batch("companies", $companies);

			$this->dbConn->insert_batch("compusers", $compusers);
		}
	}

	public function update_main_branch_details()
	{

		$tmp = $this->dbConn->select('id,mainbId')->from('companies')->get()->row_array();
		if (!$tmp)
		{
			return true;
		}
		$mainbId = !empty($tmp['mainbId'])?$tmp['mainbId']:0;
		$cId 	= !empty($tmp['id'])?$tmp['id']:0;

		$query = "select ".($mainbId?$mainbId.' as id,':'')."c.id AS cId,if(jcc.name!='',jcc.name,'Main Branch') as name,if(jcc.name!='',jcc.name,'Main Branch') AS company, if(jcc.name!='',jcc.name,'Main Branch') AS contactPerson, 'B' AS csType,c.stateCode AS stateCode,c.stateId AS stateId,ifnull(c.email,'') as email,ifnull(c.phone,'') AS contactPersonMobile,1 AS isActive,jcc.taxNo as taxNo,jcc.conTaxScheme as conTaxScheme,jcc.perTax AS perTax,-1 AS plId,1 AS 'rank',-1 as bId,cs.defBank as defaultPayAcc from ob_companies as c 
		LEFT join ob_compsettings as cs on cs.cId=c.id
		LEFT join (select cc.cId,group_concat(if(cc.code='mainBranch',cc.value,null)) as name, group_concat(if(cc.code='gstin',cc.value,null)) as taxNo,group_concat(if(cc.code='isCompositionScheme' && cc.value,'C',NULL)) as conTaxScheme,
		group_concat(if(cc.code='pan',cc.value,null)) as perTax from ob_compconfig AS cc where cc.code in ('gstin','isCompositionScheme','pan','mainBranch') group by cId) as jcc on jcc.cId=c.id where c.id=".$cId;
		$main_cont = $this->dbConn->query($query)->row_array();

		$main_cont = array_map('strval', $main_cont);

		$this->dbConn->query("SET GLOBAL sql_mode = '';");
		$this->dbConn->query("SET SESSION sql_mode = '';");

		$this->dbConn->insert('contacts', $main_cont);

		$mainbId = $mainbId?$mainbId:$this->dbConn->insert_id();
		
		$this->dbConn->where('id', $cId);
		$this->dbConn->update('companies',array('mainbId' => $mainbId));

		//contacts_address
		$addr = $this->dbConn->select('id')->from('contacts_address')->where(array('cId' => $cId, 'conId'=>$mainbId))->get()->row_array();
		
		$this->dbConn->select(($addr?$addr['id'].' as id,':'').'cp.mainbId as conId,ifnull(cp.address1,"") as address1,ifnull(cp.address2,"") as address2, cp.city, cp.stateCode, cp.stateId, cp.stateName, cp.zip, cp.countryCode, cp.country, ifnull(cp.phone,"") as phone, "" as location, ifnull(cp.email,"") as email, c.name, c.taxNo');
		$this->dbConn->from('companies as cp');
		$this->dbConn->join('contacts as c','c.id=cp.mainbId');
		$this->dbConn->where('cp.id', $cId);
		$cont_addr = $this->dbConn->get()->row_array();
		
		$cont_addr['cId']=$cId;
		$cont_addr = array_map('strval', $cont_addr);
		$this->dbConn->replace('contacts_address',$cont_addr);

		$this->dbConn->update('users',array('defaultcId' => $cId, 'defaultbId' => $mainbId));
		
		return $mainbId;				
	}

	public function company()
	{
		$data = $_POST;
		if (empty($data))
		{
			return false;
		}

		if ($this->dbConn || $this->can_connect_db())
		{
			$retData = array();
			$saveData = array();
			foreach($data as $key => $val)
			{
				if ($val) {
					$saveData[$key] = $val;
				}
			}
			unset($saveData["id"]);

			$compconfig = array();
			if (!empty($data['gstin']))
			{
				$compconfig[] = array(
					"cId" => $data["id"],
					"code" => "gstin",
					"value" => $data["gstin"]
				);
				unset($saveData['gstin']);
			}
			if (!empty($data['pan']))
			{
				$compconfig[] = array(
					"cId" => $data["id"],
					"code" => "pan",
					"value" => $data["pan"]
				);
				unset($saveData['pan']);
			}
			if (isset($data['isCompositionScheme']))
			{
				$compconfig[] = array(
					"cId" => $data["id"],
					"code" => "isCompositionScheme",
					"value" => $data["isCompositionScheme"] ? 1 : 0
				);
				unset($saveData['isCompositionScheme']);
			}
			$isPharma = false;
			if (isset($data['compType']))
			{
				$compconfig[] = array(
					"cId" => $data["id"],
					"code" => "compType",
					"value" => $data["compType"]
				);
				if (in_array($data["compType"],array('PD','PR'))) {
					$isPharma = true;
				}
				unset($saveData['compType']);
			}

			if (!empty($data["countryCode"]))
			{
				$curr = $this->dbConn->select('currencyCode')->from('countries')->where("countryCode", $data["countryCode"])->get()->row_array();
				if (!empty($curr["currencyCode"]))
				{
					$saveData["currency"] = $curr["currencyCode"];
					apply_curr_fraction($curr["currencyCode"], $this->dbConn);
				}
			}

			$this->config->load('currency_symbols', 'true');
			$country_values = $this->config->item($data["currency"], 'currency');
			if(!empty($country_values) && !empty($country_values['fyStart']))
			{
				$saveData["fyStart"] = $country_values['fyStart'];
			}
			else
			{
				$saveData["fyStart"] = 4;
			}

			$this->dbConn->set($saveData);
			$this->dbConn->where("id", $data["id"]);
			$resp = $this->dbConn->update("companies");

			$saveData["id"] = $data["id"];
			$this->_import_country_specific_sql($saveData);
/*
			if (is_file(FCPATH . 'database/outputbooks.php'))
			{
				require_once FCPATH . 'database/outputbooks.php';
				try {
					$objUpdate = new OBDatabase($this->dbConn);
					$objUpdate->updateDatabase($saveData);
					return true;
				}
				catch (Exception $ex) {
					$this->message = $ex->getMessage();
					return false;
				}
			}
*/
			$this->dbConn->insert_batch("compconfig", $compconfig);
			$this->dbConn->query("call obsptree('G');");
			$this->dbConn->query("call obsptree('C');");


			$this->installed();

			if ($isPharma) {
				// create drug license number for pharmacy
				$this->dbConn->query("INSERT INTO ".$this->dbConn->dbprefix('compfields')." (isActive, tType, fType, classCode, isPrint, isGrid, isRequired, isTotCol, fName, fOptions, fValue, orderId, cId) VALUES (1, 'CU', 'text', '', '1', 0, 0, 1, 'Drug License Number', '','',0,".$data["id"].")");
				$this->dbConn->query("INSERT INTO ".$this->dbConn->dbprefix('compfields')." (isActive, tType, fType, classCode, isPrint, isGrid, isRequired, isTotCol, fName, fOptions, fValue, orderId, cId) VALUES (1, 'SU', 'text', '', '1', 0, 0, 1, 'Drug License Number', '','',0,".$data["id"].")");
			}

			$this->update_main_branch_details();

			$this->write_output($resp, '', array());
			return true;
		}

		$this->write_output(false, 'DB Conenct error', array());
	}

/*	private function update_db_config($data=array())
	{
		$this->load->helper('file');

		$data['autoinit']	= TRUE;

		$content	= "<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');" . PHP_EOL . PHP_EOL;

		foreach ($data as $key=>$val)
		{
			if (is_numeric($val))
			{
				$content	.= "\$db[\$active_group]['" . $key . "'] = " . $val . ";" . PHP_EOL;
			}
			else if (is_bool($val))
			{
				$content	.= "\$db[\$active_group]['" . $key . "'] = " . ($val ? "TRUE" : "FALSE" ) . ";" . PHP_EOL;
			}
			else
			{
				$content	.= "\$db[\$active_group]['" . $key . "'] = '" . $val . "';" . PHP_EOL;
			}
		}

		$content	.= PHP_EOL;

		$return	= write_file($this->env_php, $content);

		@chmod($this->env_php, 0777);
		
		return $return;
	}
*/
	private function dbSettings(&$data)
	{
		$defData = array();
 		$defData['hostname'] = "localhost";
 		$defData['username'] = "root";
 		$defData['password'] = "";
 		$defData['database'] = "outputbooks";
 		$defData['dbdriver'] = "mysqli";
 		$defData['dbprefix'] = "ob_";
 		$defData['pconnect'] = false;
		$defData['db_debug'] = false;

		$data = array_merge($defData, $data);
	}

	public function db_exist()
	{
		$data	= $_POST;

		if (!empty($data) && !empty($data['db']))
		{
			$this->dbSettings($data['db']);
		}

		$result	= $this->is_db_exists($data['db']);

		if ($result)
		{
			if (is_array($result))
			{
				// $this->update_db_config($defData);
				$this->init_db_conn($data['db']);
				$this->write_output(true, $this->message, array("redirect"=>site_url()));
				return false;
			}

			$this->load->library('ob_license');
			$sysinfo = $this->ob_license->get_machine_info();

			$this->write_output(true, "", array(
				"sysinfo" => $sysinfo
			));
		}
		else
		{
			$this->write_output(false, $this->message, array());
		}
	}
	
	private function import_database()
	{
		$queries = $this->splitSql($this->database_file);

		foreach ($queries as $key=>$val)
		{
			$val = trim($val);
			if ($val)
			{
				$this->dbConn->query($val);
			}
		}

		return true;
	}

	private function _import_country_specific_sql($saveData=array())
	{
		$countrySql = FCPATH . 'database/' . $saveData["countryCode"] . '.sql';

		$queries = $this->splitSql($countrySql);

		foreach ($queries as $key=>$val)
		{
			$val = trim($val);
			if ($val)
			{
				$this->dbConn->query($val);
			}
		}

		return true;
	}

	private function splitSql($sql_file_path="")
	{
		$fp = false;

		$queries = array();

		$space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)";
		$delimiter = ";";
		$offset = 0;
		$empty = true;
		$query = "";

		$parse = '[\'"`#]|/\*|-- |$';

		if (!file_exists($sql_file_path) && !file_exists($sql_file_path.'.gz'))
		{
			return true;
		}

		$fp = @fopen((file_exists($sql_file_path) ? $sql_file_path : "compress.zlib://$sql_file_path.gz"), "rb");
		$query = ($fp ? fread($fp, 1e6) : false);

		while ($query != "")
		{
			if (!$offset && preg_match("~^$space*+DELIMITER\\s+(\\S+)~i", $query, $match))
			{
				$delimiter = $match[1];
				$query = substr($query, strlen($match[0]));
			}
			else
			{
				preg_match('(' . preg_quote($delimiter) . "\\s*|$parse)", $query, $match, PREG_OFFSET_CAPTURE, $offset); // should always match
				list($found, $pos) = $match[0];
				if (!$found && $fp && !feof($fp))
				{
					$query .= fread($fp, 1e5);
				}
				else
				{
					if (!$found && rtrim($query) == "")
					{
						break;
					}
					$offset = $pos + strlen($found);

					if ($found && rtrim($found) != $delimiter) // find matching quote or comment end
					{
						while (preg_match('(' . ($found == '/*' ? '\*/' : ($found == '[' ? ']' : (preg_match('~^-- |^#~', $found) ? "\n" : preg_quote($found) . "|\\\\."))) . '|$)s', $query, $match, PREG_OFFSET_CAPTURE, $offset)) //! respect sql_mode NO_BACKSLASH_ESCAPES
						{
							$s = $match[0][0];
							if (!$s && $fp && !feof($fp))
							{
								$query .= fread($fp, 1e5);
							}
							else
							{
								$offset = $match[0][1] + strlen($s);
								if ($s[0] != "\\")
								{
									break;
								}
							}
						}
					}
					else
					{
						// end of a query
						$empty = false;
						$q = substr($query, 0, $pos);
						$queries[] = trim($q);
						$query = substr($query, $offset);
						$offset = 0;
					}
				}
			}
		}

		return $queries;
	}

	private function splitSql_old($sql_file_path="")
	{
		$this->load->helper('file');
		$sql = read_file($sql_file_path);

		$start = 0;
		$open = false;
		$char = '';
		$end = strlen($sql);
		$queries = array();
	
		for ($i = 0; $i < $end; $i++)
		{
			$current = substr($sql, $i, 1);
			if (($current == '"' || $current == '\''))
			{
				$n = 2;
				while (substr($sql, $i - $n + 1, 1) == '\\' && $n < $i)
				{
					$n++;
				}
				if ($n % 2 == 0)
				{
					if ($open)
					{
						if ($current == $char)
						{
							$open = false;
							$char = '';
						}
					}
					else
					{
						$open = true;
						$char = $current;
					}
				}
			}
			if (($current == ';' && !$open) || $i == $end - 1)
			{
				$queries[] = substr($sql, $start, ($i - $start + 1));
				$start = $i + 1;
			}
		}
		return $queries;
	}
}
