<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
 * FIT FileRunner
 *
 * $Id$
 *
 * @author gERD Schaufelberger <gerd@php-tools.net>
 * @package FIT
 * @subpackage FileRunner
 * @license LGPL http://www.gnu.org/copyleft/lesser.html
 */

/**
 * load exception class: FileIO
 */
require_once  'Testing/FIT/Exception/FileIO.php';

/**
 * load exception class: Parser
 */
require_once  'Testing/FIT/Exception/Parser.php';


/**
 * FIT Runner
 *
 * Run fit-tests from tables stored in HTML files.
 * FileRunner provides a simple interface to process tests from CLI or
 * "remote controlled" from anther application.
 *
 * @see main()
 * @see run()
 *
 * @version 0.1.1
 * @package FIT
 * @subpackage FileRunner
 */
class Testing_FIT_Runner 
{
   
/**
    * Emulate c-stylish main() function to run applicattion on command line
    *
    * The most common usage from any script. 
    * <code> 
    *  FileRunner::main( $_SERVER['argv'] );
    * </code>
    * 
    * return codes:
    *  - 0 everything went alright
    *  - 1 invalid number of arguments
    *  - 2 file io problem
    *  - 3 parse exception
    *  - 127 unexpected exception
    * 
    * @param array argv
    * @return int 0 on success, or value greater 1 on error 
    * @see run()
    */
    
public static function main$argv ) {

       
/**
        * open stderr for writing
        * required for NON CLI misuse of FileRunner::main()
        */
        
if( !defined'STDERR' ) ) {
            throw new 
Testing_FIT_Exception_FileIO'STDERR is not defined - use PHP-CLI to call this method''STDERR' );
        }

        if( 
count$argv ) != ) {
            
fwriteSTDERR"Invalid number of arguments. input file and output file expected\n" );
            return 
1;
        }

        try {        
            
$fr = new Testing_FIT_Runner();
            
$fr->run$argv[1], $argv[2] );
        } 
        catch( 
Testing_FIT_Exception_FileIO $e ) {
            
fwriteSTDERR$e->getMessage() . "\n" );
            return 
2;
        } 
        catch( 
Testing_FIT_Exception_Parser $e ) {
            
$context    $e->getContext();
            
fwriteSTDERR$e->getMessage() . ' @ ' implode', '$context ) . "\n" );
            return 
3;
        } 
        catch( 
Exception $e ) {
            
fwriteSTDERR'Caught unknown exception: ' $e->getMessage() . "\n" );
            return 
127;
        }
        
        return 
0;
    }

   
/**
    * Process tests from file and save output
    *
    * Process all tables in input file and store result in output file. This is the API you 
    * probably want to use...
    *
    * Example:
    * <code>
    *  $fr = new Testing_FIT_Runner();
    *  $fr->run( 'infile.html', 'outfile.html' );
    * </code>
    *
    * @param string $input path to input file, or "-"  to read from STDIN
    * @param string $output path to output file, or "-"  to write to STDOUT
    * @return bool always true
    */
    
public function run$input$output )
    {
        
        
// read from STDIN
        
if( $input == '-' ) {
            
$isFile =   false;
            
            
$input  =   '';
            while( !
feofSTDIN ) ) {
                
$input  .=  freadSTDIN4096 );
            }
            
        } else {
            
$isFile =   true;
            
            
// check input file
            
if( !file_exists$input ) ) {
                throw new 
Testing_FIT_Exception_FileIO'Input file does not exist!'$input );
            }
            if( !
is_readable$input ) ) {
                throw new 
Testing_FIT_Exception_FileIO'Input file is not readable'$input );
            }            
        }        
        
        if( 
$output != '-' ) {
            
// check output file
            
if( file_exists$output ) ) {
                if( !
is_writable$output ) ) {
                    throw new 
Testing_FIT_Exception_FileIO'Output file is not writable (probably a problem of file permissions)'$output );
                }
            }
            else if( !
is_writabledirname$output ) ) ) {
                throw new 
Testing_FIT_Exception_FileIO'Cannot create output file in given folder. (probably a problem of file permissions)'$output ); 
            }
            
        }
        
        
// run and save output
        
$result =   $this->process$input$isFile );
        if( 
$output != '-' ) {
            
file_put_contents$output$result );
        } else {
            echo 
$result;
        }
        
        return 
true;
    }

   
/**
    * process tables from input
    * 
    * Run tests and return HTML.
    *
    * @param string $input source of HTML
    * @param bool $isFile whether input is a file or a string
    * @return string html output 
    */
    
public function process$input$isFile true 
    {
        
// use parser and table
        
include_once 'Testing/FIT/Parser.php';
        include_once 
'Testing/FIT/Table.php';

        if( 
$isFile ) {
            
$input      =   file_get_contents$input );
        }

        
$parser         =   new Testing_FIT_Parser();
        
$this->table    =   new Testing_FIT_Table();
        
        
$parser->parse$input );
        
$this->table->doTables$parser );

        return 
$parser->serialize();
    }
}
?>