#!/usr/bin/env --split-string=${JDK_HOME}/bin/java @Makeshift/java_arguments @Makeshift/java_javac_arguments

import Breccia.parser.*;
import Breccia.parser.plain.BrecciaCursor;
import Breccia.parser.plain.IllegalParseState;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Path;

import static Breccia.parser.plain.Project.newSourceReader;
import static java.lang.System.out;


/** A shell command to smoke test the plain Breccia parser.
  *
  *     @see <a href='http://reluk.ca/project/Breccia/parser/plain/notes.brec.xht#testing'>
  *       Usage instructions</a>
  */
public final class SmokeTestCommand { // [AFN]


    private SmokeTestCommand() {}



    public static void main( final String[] arguments ) throws IOException {
        final Path sourceFile = Path.of( arguments[0] );
        final BrecciaCursor in = new BrecciaCursor();
        try( final Reader sourceReader = newSourceReader​( sourceFile )) {
            in.source( sourceReader );
            for( ;; ) {
                final ParseState state = in.state();
                final Fractum f = in.asFractum();
                if( f != null ) {
                 // out.println( f );

                 // final CommandPoint p = in.asCommandPoint();
                 // if( p != null ) {
                 //  // out.println( p );
                 //     out.println( p.tagName() );
                 //     out.println( p.modifierSet() );
                 //     out.println( p.appendageClause() );
                 //     ; }

                    out.println( f.tagName() );
                    printComponentsOf( f, "    " );
                    ; }
                else {
                    out.print( "    " );
                    out.println( state ); }
                if( state.isFinal() ) break;
                in.next(); }}
        catch( final ParseError x ) {
            out.print( sourceFile );
            out.print( ':' );
            out.print( x.lineNumber );
            out.print( ": " );
            out.println( x ); }
         // x.printStackTrace( out ); }
        catch( final IllegalParseState x ) {
            out.print( sourceFile );
            out.print( ':' );
            out.print( x.pointer.lineNumber );
            out.print( ": " );
            out.println( x ); }}
         // x.printStackTrace( out ); }}



    private static void printComponentsOf( final Granum granum, final String indent ) throws ParseError {
        for( final Granum component: granum.components() ) {
            out.print( indent );
         // out.println( component.tagName() );
            out.println( component );
            printComponentsOf( component, indent + "    " ); }}}



// NOTE
// ────
//   AFN  Atypical file naming is allowed here.  ‘The compiler does not enforce the optional restriction
//        defined at the end of JLS §7.6, that a type in a named package should exist in a file whose
//        name is composed from the type name followed by the .java extension.’
//        <https://openjdk.org/jeps/330>
//        <https://docs.oracle.com/javase/specs/jls/se11/html/jls-7.html#jls-7.6>
//
//        No longer, however, does this allowance extend to the package name.  While in JDK releases
//        prior to 22 “the launcher's source-file mode was permissive about which package, if any,
//        was declared”, current releases enforce a correspondence between the declared package name
//        and the file path.  Failing this, the launcher aborts with “end of path to source file
//        does not match its package name”.  <https://openjdk.org/jeps/458>