<?php 

// h-source, a web software to build a community of people that want to share their hardware information.
// Copyright (C) 2010  Antonio Gallo (h-source-copyright.txt)
//
// This file is part of h-source
//
// h-source is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// h-source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with h-source.  If not, see <http://www.gnu.org/licenses/>.

if (!defined('EG')) die('Direct access not allowed!');

class SearchController extends BaseController
{

	public function __construct($model, $controller, $queryString)
	{
		
		$this->_topMenuClasses['search'] = " class='currentitem'";
		
		parent::__construct($model, $controller, $queryString);
		
		$this->model('HardwareModel');
		
		$data['title'] = 'search - '.Website::$generalName;
		$this->append($data);
	}
	
	public function form($lang = 'en')
	{
		$this->cleverLoad('form');
		$this->right();
	}

	public function results($lang = 'en')
	{
		Params::$nullQueryValue = 'undef';
		
		$argKeys = array(
			'page:forceNat'					=>	1,
			'action:sanitizeAlphanum'		=>	'search',
			'type:sanitizeString'			=>	'notebook',
			'model:sanitizeString'			=>	'undef',
		);

		$this->setArgKeys($argKeys);
		
		$this->shift(1);
		
		if (strcmp($this->viewArgs['action'],'search') === 0)
		{		
			Params::$whereClauseSymbolArray = array('like');

			$this->m['HardwareModel']->logicalOperators = array('AND','OR');
			
			$whereClause = array(
				'type'			=>	$this->viewArgs['type'],
				'level1'	=>	array(
					'model'			=>	"like '%".$this->viewArgs['model']."%'",
					'other_names'	=>	"like '%".$this->viewArgs['model']."%'",
				),
// 				'model'			=>	"like '%".$this->viewArgs['model']."%'",
// 				'other_names'	=>	"like '%".$this->viewArgs['model']."%'",
				'-deleted'		=>	"no",
				'cleared'		=>	"no",
			);

			$recordNumber =  $this->m['HardwareModel']->clear()->where($whereClause)->orderBy("id_hard desc")->rowNumber();
			
			$data['recordNumber'] = $recordNumber;
			
			//load the Pages helper
			$this->helper('Pages',$this->controller.'/results/'.$this->lang,'page');
			$page = $this->viewArgs['page'];
			//set the limit clause
			$limit = $this->h['Pages']->getLimit($page,$recordNumber,10);
			
			$data['table'] = $this->m['HardwareModel']->clear()->select('id_hard,model,type,comm_year,other_names')->where($whereClause)->limit($limit)->orderBy("id_hard desc")->send();
// 			echo $this->m['HardwareModel']->getQuery();
			
			$data['pageList'] = $this->h['Pages']->render($page-3,7);
			
			$this->append($data);
			$this->cleverLoad('results');
			$this->right();
		}
		
	}

	public function pciid($lang = 'en')
	{
		if (isset($_POST['pciid']))
		{
			$clean['pciid'] = $this->request->post('pciid','','sanitizePciid');
			$data['table'] = $this->m['HardwareModel']->clear()->select()->where(array('pci_id'=>$clean['pciid']))->send();
			$data['recordNumber'] = 0;
			
			$this->append($data);
			$this->cleverLoad('results');
			$this->right();
		}
	}

	public function lspci($lang = 'en')
	{
		if (isset($_POST['lspci']))
		{
			$data['notice'] = null;
			
			$lspci = $this->request->post('lspci','','sanitizeHtml');
			$lspciResult = array();
			$flag = true;
			
			if (strlen($lspci)<50000)
			{
				$lspci = nl2br($lspci);
				$lspciArray = explode('<br />',$lspci);
				reset($lspciArray);
				while(current($lspciArray) !== false)
				{
					$item = current($lspciArray);
					if( preg_match( '/Slot\:(.*)([0-9a-zA-Z]{2}\:[0-9a-zA-Z]{2}\.[0-9a-zA-Z]{1})/i', $item ) )
// 					if (stristr($item,'Slot'))
					{
						$temp = array();
// 						class
						if (next($lspciArray) !== false)
						{
							$item = trim(current($lspciArray));
							if( preg_match( '/Class\:(.*)\[(.*)\]/i', $item, $matches ) )
							{
								$temp['className'] =  sanitizeAll($matches[1]);
								$temp['classId'] =  sanitizeAll($matches[2]);
							}
							else
							{
								$temp['className'] = "unknown";
								$temp['classId'] =  "unknown";
							}
						}
						else
						{
							$flag = false;
							break;
						}
						
// 						vendor
						if (next($lspciArray) !== false)
						{
							$item = trim(current($lspciArray));
							if( preg_match( '/Vendor\:(.*)\[(.*)\]/i', $item, $matches ) )
							{
								$temp['vendorName'] =  sanitizeAll($matches[1]);
								$temp['vendorId'] =  sanitizeAll($matches[2]);
							}
							else
							{
								$temp['vendorName'] = "unknown";
								$temp['vendorId'] =  "unknown";
							}
						}
						else
						{
							$flag = false;
							break;
						}
						
// 						device
						if (next($lspciArray) !== false)
						{
							$item = trim(current($lspciArray));
							if( preg_match( '/Device\:(.*)\[(.*)\]/i', $item, $matches ) )
							{
								$temp['deviceName'] =  sanitizeAll($matches[1]);
								$temp['deviceId'] =  sanitizeAll($matches[2]);
							}
							else
							{
								$temp['deviceName'] = "unknown";
								$temp['deviceId'] =  "unknown";
							}
						}
						else
						{
							$flag = false;
							break;
						}
						
						$lspciResult[] = $temp;
					}
					next($lspciArray);
				}
				if (count($lspciResult) === 0 or $flag === false)
				{
					$data['notice'] = "<div class='alert'>".gtext('the text submitted by you does not seem to be the lspci -vmmnn output. Please check the text and try again')."</div>\n";
					$flag = false;
				}
			}
			else
			{
				$data['notice'] = "<div class='alert'>the lspci output is too long</div>\n";
				$flag = false;
			}

			$data['flag'] = $flag;
			
			$data['table'] = array();
			$data['notFoundDevices'] = array();
			
			if ($flag)
			{
				$lspciFiltered = array();
				$vendorIDProductIDArray = array();
				foreach ($lspciResult as $device)
				{
					if (array_key_exists($device['classId'],Hardware::$deviceClasses))
					{
						$vendorIDProductIDArray[] = sanitizePciid($device['vendorId'].":".$device['deviceId']);
						$lspciFiltered[] = $device;
					}
				}
				if (count($vendorIDProductIDArray) > 0)
				{
					$whereString = "'".implode("','",$vendorIDProductIDArray)."'";
					$data['table'] = $this->m['HardwareModel']->select()->where(array('pci_id'=>"in($whereString)"))->send();

					$foundPciidArray = $this->m['HardwareModel']
										->select('pci_id')
										->where(array('pci_id'=>"in($whereString)"))
										->toList('pci_id')
										->send();

					$notFoundDevices = array(); //list of devices not found inside the database
					$notFoundPciIdList = array(); //to check that it does not take the same device twice
					
					foreach ($lspciFiltered as $device)
					{
						if (!in_array($device['vendorId'].":".$device['deviceId'],$foundPciidArray))
						{
							if (!in_array($device['vendorId'].":".$device['deviceId'],$notFoundPciIdList))
							{
								$notFoundDevices[] = $device;
								$notFoundPciIdList[] = $device['vendorId'].":".$device['deviceId'];
							}
						}
					}

					$data['notFoundDevices'] = $notFoundDevices;
				}
				
			}
			$this->append($data);
			$this->cleverLoad('lspci_results');
			$this->right();
		}
	}
}