#!/usr/local/bin/php
<?php
require "Console/Getopt.php";
define("SUITE_END", "End of Test Suite");

/**
* phpcuppa : phpTestSuiteġ
*
* ѥ᡼ȤˡphpunitѤTestSuite(Skelton)롣<BR>
* License: MIT License
* @package phpcuppa
* @access public
* @version 0.1
* @author Furukawa Atsushi <agl@violet.plala.or.jp>
* @since 2002/08/13
*/
class  phpcuppa {
	var $main  = "runtest";	/** @var string $main	main file */
	var $skelton;	/** @var string $skelton	main class name */
	var $include;	/** @var string[] $include	include class list */
	var $basedir;	/** @var string $basedir	include base directory */
	var $is_cin = FALSE;	/** @var boolean $is_cin 	from stdin flag */
	var $is_help = FALSE;	/** @var boolean $is_help	output help */
	var $is_version = FALSE;	/** @var boolean $is_version output version */
	var $suites;	/** @var string[] $suites	test suite list */

	var $opt_short = "h?vm:s:b:i:";	/** @var string	option(short) */
	var $opt_long = array(	/** @var string[]	option(long) */
		"help",
		"version",
		"main=",
		"skelton=",
		"basedir=",
		"include="
	);

	/**
	* 󥹥ȥ饯
	* @param string[] $args  ޥɥ饤󡦥ץ
	*/
	function phpcuppa($args = NULL)
	{
		if (isset($args)) {
			$this->getopt($args);
		}
	}

	/**
	* ץ
	*
	* ѥ᡼饪ץͤꤹ
	* @param string[] $args ѥ᡼
	*/
	function getopt($args)
	{
		$this->is_cin = $this->is_cin($args);
		$con = new Console_Getopt;
		$opts = $con->getopt($args, $this->opt_short, $this->opt_long);
		$max = count($opts[0]);
		$is_mainset = FALSE;
		for ($i=0; $i<$max; $i++) {
			switch ($opts[0][$i][0]) {
			case "h":
			case "?":
			case "--help":
				$this->is_help = TRUE;
				break;

			case "v":
			case "--version":
				$this->is_version = TRUE;
				break;

			case "s":
			case "--skelton":
				$this->skelton = $opts[0][$i][1];
				if (!$is_mainset) {
					$this->main = $opts[0][$i][1];
				}
				break;

			case "m":
			case "--main":
				$is_mainset = TRUE;
				$this->main = $opts[0][$i][1];
				break;

			case "b":
			case "--basedir":
				$this->basedir = $opts[0][$i][1];
				break;

			case "i":
			case "--include":
				$this->include[] = $opts[0][$i][1];
				break;
			}
		}
		$this->suites = $opts[1];
	}


	/**
	* ɸϥե饰å
	*
	* "-cin"ޤޤƤ뤫å롣
	* @param string[] $args  ޥɥ饤󥪥ץ
	*/
	function is_cin(&$args)
	{
		$is_cin = FALSE;
		$max = count($args);
		for ($i=0; $i<$max; $i++) {
			if ($args[$i] == "-cin") {
				$is_cin = TRUE;
				unset($args[$i]);
			}elseif ($args[$i]=="" || $args[$i]==NULL) {
				unset($args[$i]);
			}
		}
		if ($is_cin) {
			$args = array_values($args);
		}
		return $is_cin;
	}

	/**
	* եإå
	*/
	function  output_file_header()
	{
		$output = "<?php
require_once 'phpunit.php';
";
		$max = count($this->include);
		if ($max > 0) {
			for ($i=0; $i<$max; $i++) {
				if ($this->basedir == "") {	$output .= "require '" . $this->include[$i] . "';\n"; }
				else {						$output .= "require '" . $this->basedir . "/" . $this->include[$i] . "';\n"; }
			}
		}
		return $output;
	}

	/**
	* եեå
	*/
	function  output_file_footer()
	{
		$output= "";
		if (isset($this->skelton) && $this->skelton!="") {
			$output = '
$suite = new TestSuite("' . $this->skelton . '");
$tr = new TestRunner();
$tr->run($suite);
?>
';
		}
		return $output;
	}

	/**
	* 饹إå
	*/
	function  output_class_header()
	{
		$output = "";
		if (isset($this->skelton) && $this->skelton!="") {
			$output = '
class  ' . $this->skelton . '  extends TestCase {
	function ' . $this->skelton . '($name)
	{
		$this->TestCase($name);
	}

	function setUp()
	{
	}

	function tearDown()
	{
	}
';
		}
		return $output;
	}

	/**
	* ƥȥ᥽åɽ
	*/
	function output_test_suite($name)
	{
		$output = "";
		if ($name != "") {
			$output = '
	function ' . $name . '()
	{
		$this->fail("no implementation");
	}
';
		}
		return $output;
	}

	/**
	* 饹եå
	*/
	function output_class_footer()
	{
		$output =
'	//CUPPA:' . SUITE_END . '
}
';
		return $output;
	}

	/**
	* suite
	* suiteΰ顢ꤷsuite
	* @param string $suite
	*/
	function suite_delete($suite)
	{
		$max = count($this->suites);
		$is_delete = FALSE;
		for ($i=0; $i<$max; $i++) {
			if ($this->suites[$i] == $suite){
				unset($this->suites[$i]);
				$is_delete = TRUE;
			}
		}
		if ($is_delete){ $this->suites = array_values($this->suites); }
	}

	/**
	*  
	*/
	function suite_new()
	{
		if ($this->skelton == "")	return FALSE;
		$fp = fopen($this->main . ".php.new", "w");
		if (!$fp)					return FALSE;
		fputs($fp, $this->output_file_header());
		fputs($fp, $this->output_class_header());
		for ($i=0; $i<count($this->suites); $i++) {
			fputs($fp, $this->output_test_suite($this->suites[$i]));
		}
		fputs($fp, $this->output_class_footer());
		fputs($fp, $this->output_file_footer());
		fclose($fp);
		return TRUE;
	}

	/**
	*  ƥɲ
	*/
	function suite_append()
	{
		$fp_in = fopen($this->main . ".php", "r");
		if (!$fp_in) 					return FALSE;
		$fp_out = fopen($this->main . ".php.new", "w");
		if (!$fp_out) { fclose($fp_in);	return FALSE; }
		while ($line = fgets($fp_in)){
			$func = get_function($line);
			if ($func != "")  $this->suite_delete($func);
			if (strstr($line, SUITE_END)) {
				for ($i=0; $i<count($this->suites); $i++) {
					fputs($fp_out, $this->output_test_suite($this->suites[$i]));
				}
			}
			fputs($fp_out, $line);
		}
		fclose($fp_out);
		fclose($fp_in);
		return TRUE;
	}

	/**
	* suite
	*/
	function suite_create()
	{
		$file = $this->main . ".php";
		if (file_exists($file)) {
			$er = $this->suite_append();
		} else {
			$er = $this->suite_new();
		}
		if ($er) {
			if (file_exists($file)) unlink($file);
			$er = rename($file . ".new", $file);
		}
		return $er;
	}
}

/**
 * ؿ̾
 *
 * ɤߤԤؿ̾
 * @param string $line  ɤߤ߹
 */
function get_function($line)
{
	$er = ereg("function[ \t]+([^.(]*)\(", $line, $func);
	if ($er) {
		return $func[1];
	} else {
		return "";
	}
}

/**
* Versionɽ
* @param string
*/
function version()
{
	print "phpcuppa Ver 1.00 Copyright 2003/02/14(Fri) by phpcuppa project\n";
}


/**
* إɽ
*/
function help()
{
	global $Program;
	print "$Program [-cin] [-m <name>] [-s <name>] [test_1 [test_2 [...]]]\n";
	print '
--cin                : ɸϤѥ᡼ϡ
--help, -h,-?        : إײ̤ɽ
--main,    -m <name> : ϥե̾
--skelton, -s <name> : 륯饹̾
--include, -i <file> : requireե̾
--basedir, -b <dir>  : requireˤĤǥ쥯ȥ̾
--version, -v        : Versionɽ
';
}

/**
* ѥ᡼ɸϤɤߤߡTestSuite
*/
function make_from_stdin()
{
	$fp = fopen("php://stdin", "r");
	if (!$fp) return FALSE;
	while ($line = fgets($fp, 4000)) {
		$args = split("[ \t\n]+", $line);
		$ph = new phpcuppa($args);
		$ph->suite_create();
	}
	fclose($fp);
}

/**
* ᥤ롼
*/
$args = Console_Getopt::readPHPArgv();
@$Program = $args[0];	// ƬΥץ̾
$ph = new phpcuppa($args);

if ($ph->is_help) {
	help();
}else if ($ph->is_version) {
	version();
}else{
	if ($ph->is_cin){ make_from_stdin(); }
	$ph->suite_create();
}
?>
