<?php
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @category   tests
 * @package    log4php
 * @subpackage appenders
 * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @link       http://logging.apache.org/log4php
 */

/**
 * @group appenders
 */
class LoggerAppenderSocketTest extends PHPUnit_Framework_TestCase {

	/** Port on which the socket server will run. */
	const SOCKET_PORT = 12345;

	/** The socket server process resource. */
	private $server;
	
	/** The pipes array for the server process. */
	private $pipes;
	
	public function setUp() {
		Logger::clear();
	}
	
	public function tearDown() {
		Logger::clear();
	}
	
	public function testRequiresLayout() {
		$appender = new LoggerAppenderSocket();
		self::assertTrue($appender->requiresLayout());
	}
	
	public function testLogging()
	{
		Logger::configure(array(
		    'appenders' => array(
		        'default' => array(
		            'class' => 'LoggerAppenderSocket',
		            'params' => array(
		                'remoteHost' => 'localhost',
		                'port' => self::SOCKET_PORT
		            ),
		            'layout' => array(
		            	'class' => 'LoggerLayoutSimple'
		            )
		        ),
		    ),
		    'rootLogger' => array(
		        'appenders' => array('default'),
		    ),
		));

		$this->startServer();
		
		$logger = Logger::getLogger("myLogger");
		$logger->trace("This message is a test");
		$logger->debug("This message is a test");
		$logger->info("This message is a test");
		$logger->warn("This message is a test");
		$logger->error("This message is a test");
		$logger->fatal("This message is a test");
		
		$actual = $this->getPlayback();
		$this->stopServer();
		
		$expected = "DEBUG - This message is a test" . 
		            "INFO - This message is a test" . 
		            "WARN - This message is a test" . 
		            "ERROR - This message is a test" . 
		            "FATAL - This message is a test";

		$this->assertEquals($expected, $actual);
	}
	
	/** Starts a socket server in a separate process. */
	private function startServer() {
		$serverLog = PHPUNIT_TEMP_DIR . '/socketServer.log';
		$descriptorspec = array(
			0 => array("pipe", "r"),  // stdin
			1 => array("file", $serverLog, "a"),// stdout
			2 => array("file", $serverLog, "a") // stderr
		);

		$cmd = "php " . dirname(__FILE__) . '/socketServer.php';
		$this->server = proc_open($cmd, $descriptorspec, $this->pipes);
		if ($this->server === false) {
			throw new Exception("Failed starting the socket server process.");
		}
		
		// Sleep a bit to allow server to start
		usleep(200000);
		
		// Verify the server is running
		$status = proc_get_status($this->server);
		if (!$status['running']) {
			throw new Exception("Socket server process failed to start. Check the log at [$serverLog].");
		}
	}
	
	/** Sends a message to the socket server and returns the reply. */
	private function socketSend($msg) {
		$sock = fsockopen('localhost', self::SOCKET_PORT, $errno, $errstr);
		if ($sock === false) {
			throw new Exception("Unable to open socket. Error: [$errno] $errstr");	
		}
		
		fputs($sock, "$msg\n");
		$reply = '';
		while(!feof($sock)) {
			$reply .= fgets($sock);
		}
		fclose($sock);
		return trim($reply);
	}
	
	/** Retrieves a playback of all sent messages from the socket server. */
	private function getPlayback() {
		return $this->socketSend('playback');
	}
	
	/** Stops the socket server and closes the process. */
	private function stopServer() {
		$this->socketSend('shutdown');
		foreach($this->pipes as $pipe) {
			fclose($pipe);
		}
		proc_close($this->server);
	}
}
