<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * This class is able to collect traffic information for iiNet ADSL
 *
 * Traffic information is collected by each service, and cached,
 * returning just the date in question.
 *
 * @package    ADSL
 * @category   Service
 * @author     Deon George
 * @copyright  (c) 2009-2013 Open Source Billing
 * @license    http://dev.osbill.net/license.html
 */
class Service_Traffic_ADSL_iiNetADSL extends Service_Traffic_ADSL {
	private $login_user_field = 'username';
	private $login_pass_field = 'password';
	private $date_field = 'period';

	static $result = array();

	// The fields in the XML which are translated into database columns
	private $fields = array(
		'peak'=>'down_peak',
		'offpeak'=>'down_offpeak',
		'uploads'=>'up_peak',
		'freezone'=>'internal',
	);

	/**
	 * Get the data for iiNet ADSL services
	 *
	 * @return array
	 */
	protected function getdata($date) {
		// Assume we have a bad fetch, unless otherwise specified.
		$this->fetchresult = FALSE;

		// If we have already collected the date data, return it.
		if (! empty(Service_Traffic_ADSL_iiNetADSL::$result[$date]))
			return Service_Traffic_ADSL_iiNetADSL::$result[$date];

		// Find our services that need to be collected this way.
		$update = array();
		foreach ($this->aso->services() as $so) {
			if ($so->service_adsl->service_stats_collect AND $so->service_adsl->service_stats_lastupdate < $date) {
				$lastperiod = '';
				for ($servicedate=date('Y-m-d',strtotime($this->aso->stats_lastupdate.'+1 day'));
					$servicedate <= $this->today;
					$servicedate=date('Y-m-d',strtotime('+1 day',strtotime($servicedate)))) {

					$debug = FALSE;
					$debug_file = '/tmp/data';

					// IINET gives us data a month at a time.
					if ($lastperiod != date('Ym',strtotime($servicedate))) {
						$lastperiod = date('Ym',strtotime($servicedate));

						$postfields = http_build_query(array(
							$this->login_user_field=>$so->service_adsl->service_username,
							$this->login_pass_field=>$so->service_adsl->service_password,
							'period'=>$lastperiod,
							'usage_view'=>'month',
							'action'=>'login',
						));

						if ($debug AND file_exists($debug_file))
							$data = file_get_contents($debug_file);
						else
							$data = Remote::get($this->aso->stats_url,$this->curlopts+array(CURLOPT_POSTFIELDS=>$postfields));

						// @todo There exists a possibility to skip a month, if we get a bad fetch on a previous month.
						if ($data)
							$this->fetchresult = TRUE;

						if ($debug AND ! file_exists($debug_file))
							file_put_contents($debug_file,$data);
					}

					$result = array();
					foreach (XML::factory(NULL,'ii_feed',$data)->volume_usage->volume_usage->get('day_hour') as $day_hour) {
						$attrs = array();

						$period = $day_hour->attributes();
						// If we find a field we dont understand, we'll return.
						if (empty($period['period']))
							return array();

						foreach ($day_hour->get('usage') as $usage) {
							$fields = $usage->attributes();

							// If we find a field we dont understand, we'll return.
							if (empty($fields['type']) OR empty($this->fields[$fields['type']]))
								return array();

							// Traffic is in bytes, need to convert to MB
							if (empty($attrs[$this->fields[$fields['type']]]))
								$attrs[$this->fields[$fields['type']]] = $usage->value()/1000/1000;
							else
								$attrs[$this->fields[$fields['type']]] += $usage->value()/1000/1000;
						}

						Service_Traffic_ADSL_iiNetADSL::$result[$period['period']][$so->service_adsl->service_username] = $attrs;
						Service_Traffic_ADSL_iiNetADSL::$result[$period['period']][$so->service_adsl->service_username]['date'] = $period['period'];
						Service_Traffic_ADSL_iiNetADSL::$result[$period['period']][$so->service_adsl->service_username]['service'] = $so->service_adsl->service_username;
					}
				}

				// If we got here and have data, we had a good fetch, update the stats date
				$so->service_adsl->service_stats_lastupdate = $date;
				$so->service_adsl->save();
			}
		}

		// If the date we want is empty, return an array
		if (empty(Service_Traffic_ADSL_iiNetADSL::$result[$date]))
			return array();

		// Return the date we asked for
		return Service_Traffic_ADSL_iiNetADSL::$result[$date];
	}
}
?>
