#!/usr/bin/env --split-string=${JDK_HOME}/bin/java @Makeshift/java_arguments @Makeshift/java_javac_arguments \c [SS]

// This command runs directly from the present source file, it needs no compiling.

import Breccia.parser.plain.BrecciaCursor;
import Breccia.Web.imager.BreccianFileTranslator;
import Breccia.Web.imager.FileTranslator;
import Breccia.Web.imager.ImageMould;
import Breccia.XML.translator.BrecciaXCursor;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import wayic.Waybrec.parser.WaybrecCursor;
import wayic.Web.imager.ImagingOptions;
import wayic.Web.imager.Project;
import wayic.Web.imager.WaybreccianFileTranslator;

import static Breccia.Web.imager.ImagingCommands.image;
import static java.lang.System.err;
import static java.lang.System.exit;


/** A shell command to make a Web image.
  *
  *     @see <a href='http://reluk.ca/project/wayic/Web/imager/bin/waycast-web-image.brec.xht'>
  *       The `waycast-web-image` command</a>
  */
public final class WaycastWebImageCommand implements AutoCloseable { // [AFN]


    /** @param argsN Nominal arguments, aka options.
      * @param argsP Positional arguments.
      */
    private WaycastWebImageCommand( final  List<String> argsN, final List<String> argsP ) {
        opt.initialize( argsN );
        final int n = argsP.size();
        if( n != 1 ) {
            err.println( commandName + ": Expecting 1 argument, found " + n );
            exitWithUsage( err, 1 ); }
        boundaryPath = Path.of(argsP.get(0)).toAbsolutePath().normalize(); }



    /** Takes a `waycast-web-image` command from the shell and executes it.
      */
    public static void main( final String[] arguments ) {
        final var argsN = new ArrayList<String>();
        final var argsP = new ArrayList<String>();
        for( final String arg: arguments ) {
            exitOnDemand( arg );
            (arg.charAt(0) == '-' ? argsN : argsP).add( arg ); }
        try( final var command = new WaycastWebImageCommand( argsN, argsP )) {
            if( !command.run() ) exit( 1 ); }}



   // ━━━  A u t o   C l o s e a b l e  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


    public @Override void close() { sourceXCursor.close(); }



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


    private final Path boundaryPath;



    private static final String commandName = "waycast-web-image";



    private static void exitOnDemand( final String arg ) {
        if( arg.equals("-?") || arg.equals("-help") ) exitWithUsage( System.out, 0 ); }



    private static void exitWithUsage( final PrintStream sP, final int status ) {
        sP.println( "Usage: " + commandName + " [<options>] <boundary path>" );
        sP.println( "       " + commandName + " -help | -?" );
        sP.println( "Options, one or more of:" );
        sP.println( "    -author-home-directory=<file path>" );
        sP.println( "    -centre-column=<number>" );
        sP.println( "    -co-service-directory=<URI reference>" );
        sP.println( "    -exclude=<pattern>" );
        sP.println( "    -fake" );
        sP.println( "    -force" );
        sP.println( "    -glyph-test-font=<file path> | none" );
        sP.println( "    -math" );
        sP.println( "    -reference-mapping=;<pattern>;<replacement>; [|| ;<pattern>;<replacement>;] ..." );
        sP.println( "    -speak" );
        sP.println( "    -stifle" );
        sP.println( "    -verbosity=0|1|2" );
        exit( status ); }



    private final ImagingOptions opt = new ImagingOptions( commandName );



    /** @return True on success, false on failure.
      */
    private boolean run() {
        return image( commandName, boundaryPath, opt, new TranslatorMaker(), Project.outputDirectory ); }



    private final BrecciaXCursor sourceXCursor = new BrecciaXCursor();



   // ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀


    private final class TranslatorMaker implements FileTranslator.Maker<WaybrecCursor> {


        public @Override FileTranslator<WaybrecCursor> newTranslator( ImageMould<?> mould ) {
            final var t = new BreccianFileTranslator<>( new BrecciaCursor(), sourceXCursor, mould );
            final var tW = new WaybreccianFileTranslator( new WaybrecCursor(), sourceXCursor, mould, t,
              opt );
            return tW; }}}



// NOTES
// ─────
//   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>
//
//   SS · Here the long form `--split-string` (as opposed to `-S`) enables Emacs to recognize this file
//        as Java source code.  See the note apropos of ‘source-launch files encoded with a shebang’ at
//        `http://reluk.ca/project/Java/Emacs/jmt-mode.el`.



                                                   // Copyright © 2020-2024  Michael Allan.  Licence MIT.