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

import Breccia.parser.ParseError;
import Breccia.parser.plain.BrecciaCursor;
import Breccia.XML.translator.BrecciaXCursor;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Path;
import javax.xml.stream.XMLStreamException;

import static Breccia.parser.plain.Project.newSourceReader;
import static Breccia.XML.translator.BrecciaXCursor.EMPTY;
import static java.lang.System.err;
import static java.lang.System.out;
import static javax.xml.stream.XMLStreamConstants.*;


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


    private SmokeTestCommand( Path sourceFile ) { this.sourceFile = sourceFile; }



    public static void main( final String[] arguments ) throws IOException, XMLStreamException {
        new SmokeTestCommand( Path.of( arguments[0] )).execute(); }



////  P r i v a t e  ////////////////////////////////////////////////////////////////////////////////////


    private void execute() throws IOException, XMLStreamException {
        try( final Reader sourceReader = newSourceReader​( sourceFile );
             final BrecciaXCursor sourceXCursor = new BrecciaXCursor() ) {
            final BrecciaCursor sourceCursor = new BrecciaCursor();
            sourceCursor.source( sourceReader );
            sourceXCursor.source( sourceCursor );
            for( final BrecciaXCursor in = sourceXCursor;; ) {
                switch( in.getEventType() ) {
                    case CHARACTERS -> {}
                    case EMPTY -> out.println( "Empty source file" );
                    case END_DOCUMENT -> {}
                    case END_ELEMENT -> {
                        indent();
                        out.print( in.getLocalName() );
                        out.println();
                        --indent; }
                    case START_DOCUMENT -> {}
                    case START_ELEMENT -> {
                        indent();
                        out.print( in.getLocalName() );
                        out.println();
                        ++indent; }
                    default -> throw new IllegalStateException(); } /* The event type being
                      either `HALT`, or one not actually emitted by `BrecciaXCursor` at the time
                      of coding.  For the event types emitted, see the `assert` statement
                      and comment at the foot of method `BrecciaXCursor.next`. */
                if( !in.hasNext() ) break;
                try { in.next(); }
                catch( final XMLStreamException x ) { throw (ParseError)(x.getCause()); }}}
        catch( final ParseError x ) {
            err.print( sourceFile );
            err.print( ':' );
            err.print( x.lineNumber );
            err.print( ": " );
            err.println( x ); }}



    private int indent;



    private void indent() { for( int i = 0; i < indent; ++i ) out.print( "    " ); }



    private final Path sourceFile; }



// 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>