001package Torello.Java.Build;
002
003import Apache.CLI.Options;
004import Apache.CLI.OptionGroup;
005
006import Torello.Java.UnreachableError;
007import Torello.Java.StrCmpr;
008
009import Torello.Java.ReadOnly.ReadOnlyList;
010
011import Torello.Java.Additional.ByRef;
012import Torello.Java.Additional.Ret4;
013
014import static Torello.Java.C.BCYAN;
015import static Torello.Java.C.RESET;
016
017import java.util.ArrayList;
018import java.util.List;
019import java.util.Objects;
020
021/**
022 * This data class is instantiated by parsing the Command-Line Input.  It contains the settings
023 * that were extrapolated by the Apache CLI Parser. 
024 * 
025 * <!-- Contains the black-banner declaring this is a CLI-group internally used class -->
026 * <EMBED CLASS='external-html' DATA-FILE-ID=CLI_INTERNAL_USE>
027 * 
028 * <BR /><B CLASS=JDDescLabel>Retrieving an Instance:</B>
029 * 
030 * <BR />With the above provided notice, if you still wish to view the contents of this class, the
031 * Object-Reference that is used by {@link RunBuild} is one of the myriad field's that are made
032 * available within the class {@link BuilderRecord}.
033 * 
034 * <BR /><BR />A {@link BuilderRecord} instance is generated as follows, and the {@code CLI} 
035 * instance is obtained by referencing the field {@link BuilderRecord#cli cli}, as below:
036 * 
037 * <DIV CLASS=EXAMPLE>{@code
038 * public static void main(String[] argv)
039 * {
040 *      Config config = new Config();
041 * 
042 *      // Perform as many assignments to the Configuration-Fields as is necessary!
043 *      // ... [Configurations Here] ...
044 *      //see class Config to learn about all available Config-Fields]
045 * 
046 *      BuilderRecord brec = config.createBuilder(argv);
047 * 
048 *      // Print's out the contents of this class...
049 *      System.out.println(brec.cli);
050 * 
051 *      // Run's the Build, using all User-Provided Configurations obtained from class Config,
052 *      // along with all User-Specified Options provided at the OS Command-Prompt
053 * 
054 *      RunBuild.run(brec);
055 * }
056 * }</DIV>
057 * 
058 * <BR /><BR />The datum contained as fields of this class are all declared {@code public} and also
059 * {@code ReadOnly} or {@code final}.  The instance generated from the Command-Line Input (CLI)
060 * parser is available as a {@code public} and {@code final} field of the {@link BuilderRecord}
061 * instance field {@link BuilderRecord#cli};
062 * 
063 * <BR /><BR />This class does not offer any public constructors, nor any public methods.  It is 
064 * automatically built by class {@code Builder}, which has package-level access to this class' sole
065 * constructor.
066 * 
067 * <EMBED CLASS='external-html' DATA-FILE-ID=CLI_MENU>
068 * <EMBED CLASS='external-html' DATA-FILE-ID=CLI_SWITCHES>
069 */
070public class CLI
071{
072    // ********************************************************************************************
073    // ********************************************************************************************
074    // Fields
075    // ********************************************************************************************
076    // ********************************************************************************************
077
078
079    /**
080     * To-Do: Create a detailed explanation of this sick little bugger.
081     * 
082     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
083     * @see BuildPackage#QUICKER_BUILD_SKIP
084     */
085    public final boolean QUICKER_BUILD;
086
087    /**
088     * There is a way to request that your {@code '.html'}-Files have Meta-Data inside their
089     * File-Headers stating that they <B STYLE='color: red;'>do not wish</B> the user's Web-Browser
090     * to Cache their Java-Doc {@codde '.html'}-Files.
091     * 
092     * <BR /><BR />If you are including documentation pages as a part of your Build-Process, then
093     * "re-uploading" your Java-Doc {@code '.html'} Pages will be as important as re-compiling and
094     * testing your code.
095     * 
096     * <BR /><BR />If you are intending to visit, and re-visit a particular Web-Address in whatever
097     * browser you are using to view your Java-Doc output, then making sure that
098     * <B STYLE='color: red'><I>your browser does not cache your Web-Pages</I></B> will save you an
099     * endless amount of head-ache.
100     * 
101     * <BR /><BR />Wiping your Google Chrome's Cache manually can be a real disaster when your
102     * saved Form-Field answers are erased, along with your saved Search-Requests or even your
103     * passwords!
104     * 
105     * <BR /><BR /><B CLASS=JDDescLabel>How it's Used:</B>
106     * 
107     * <BR />This field is manually populated by the internal CLI-Option Building-Class.  All that 
108     * is occuring is that, internally, a list of class {@link CLI} Main-Menu Options which
109     * indicate / necessitate that <B STYLE='color: red'>Stage 8, Set Max Age</B> was entered, by
110     * the user, at the command line.
111     * 
112     * <BR /><BR />If the User-Selected {@link SelectedOptionsRecord#MENU_CHOICE MENU_CHOICE} is
113     * among the known Stage-8 options, then this field will contain {@code TRUE}.
114     * 
115     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
116     */
117    public final boolean sma_NoBrowserCache_OptionSelected;
118
119    /**
120     * This field is assigned {@code TRUE} when a "Partial Build"
121     * {@link SelectedOptionsRecord#MENU_CHOICE MENU_CHOICE} has been selected by the user, at the
122     * Command-Line, and that choice is one of the choices that requests Step / Stage 5
123     * (Synchronize all {@code '.html'} Files) be run.
124     * 
125     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
126     */
127    public final boolean partialWithSync_OptionSelected;
128
129    /**
130     * This field is assigned {@code TRUE} if-and-only-if the Composite-Step Menu-Option
131     * associated with running Primary-Steps / Primary-Stages #1 to #4 has been selected by the
132     * user.
133     * 
134     * <BR /><BR />This boolean is required by the {@link RunBuild} class in order to decide
135     * whether or not to run the Stage-4 (Archive / Tar / Jar) Process for a Composite-Build.
136     * 
137     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
138     * 
139     * @see RunBuild#run(BuilderRecord)
140     */
141    public final boolean compositeStep_RunStage2to4_OptionSelected;
142
143    /**
144     * This record is generated based on the Terminal-Input from {@code 'String[] argv'}.
145     * 
146     * <BR /><BR />As soon as the Apache-CLI Options are generated, they are compared against the
147     * User's {@code String[] argv} input, and this record is created.
148     */
149    public final SelectedOptionsRecord sor;
150
151    /**
152     * This Record contains exactly 7 {@code final-boolean} fields, each of which corresponds to
153     * exactly one of the available Command-Line Terminal Main-Menu Auxialiary-option Switches.
154     * 
155     * <BR /><BR />Whenever a user passes a Command-Line Auxiliary Option / Switch at to the
156     * {@code String[] argv} parameter, it will be reflected inside this {@code final} class.
157     * 
158     * @see ErrorCheckAuxOpts
159     */
160    public final AuxiliaryOptRecord aor;
161
162
163    // ********************************************************************************************
164    // ********************************************************************************************
165    // Process the Command-Line Arguments
166    // ********************************************************************************************
167    // ********************************************************************************************
168
169
170    CLI(
171            final ReadOnlyList<CloudSync>       cloudSyncList,
172            final ReadOnlyList<BuildPackage>    packageList,
173            final String[]                      argv,
174            final ByRef<CloudSync>              selectedCloudSync,  // Return-By-Reference Wrapper
175            final StringBuilder                 dataRecLogSB
176        )
177    {
178        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
179        // Generate an Apache.CLI.Options instance
180        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
181        //
182        // class 'OptionRecord' contains / creates a list of Apache-CLI Options.
183        // 
184        // While creating these classes, the calculations produce interim values that are saved.
185        // These saved values are then re-used and inserted into the fields...  These are all of
186        // the fields contained in the "OptionsRecord"
187        // 
188        // r4.a: Apache.CLI.Options
189        // r4.b: Apache.CLI.OptionGroup
190        // r4.c: CollatedOptsRecord
191        // r4.d: PrintHelpRecord
192        // 
193        // CollatedOptsRecord Contents:
194        // 
195        // public final ReadOnlyList<String> optionsWhichAcceptPkgNickNames;
196        // public final ReadOnlyMap<String, CloudSync> cloudSyncSwitchMapper;
197        // public final ReadOnlyList<String> smaRequested_optionsList;
198        // public final ReadOnlyList<String> partialWithSync_List;
199        // public final String compositeStep_RunStage2to4_OptionName;
200        // 
201        // These records are "ephemeral" or short-lived.  After this class constructor is finished,
202        // these records can be cleaned by the Java Garbag-Collector.
203        // 
204        // These records are, literally, only used inside this constructor for processing the
205        // User's Command-Line Input (String[] argv parameter) against the contents of his 
206        // Configurations - package-list (of Java-Packages), and CloudSync-List (of Cloud Storage
207        // Bucket destinations / targets).
208
209        Ret4<Options, OptionGroup, CollatedOptsRecord, PrintHelpRecord> r4 =
210            Generate.generate(cloudSyncList);
211
212        final Options               options = r4.a; // Apache.CLI.Options
213        final OptionGroup           group   = r4.b; // Apache.CLI.OptionsGroup
214        final CollatedOptsRecord    cor     = r4.c; // Torello.Java.Build.CollatedOptRecord
215        final PrintHelpRecord       phr     = r4.d; // Torello.Java.Build.PrintHelpRecord
216
217        dataRecLogSB.append(
218            Printing.DATA_REC_LOG_LINES +
219            "CollatedOptsRecord:\n" + 
220            Printing.DATA_REC_LOG_LINES + '\n' +
221            cor.toString() + "\n\n" +
222
223            Printing.DATA_REC_LOG_LINES +
224            "PrintHelpRecord:\n" + 
225            Printing.DATA_REC_LOG_LINES + '\n' +
226            phr.toString() + "\n\n"
227        );
228
229
230        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
231        // Process, and Error-Check, the Main-Menu Choice
232        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
233        //
234        // This Class/Method Generates a 'SeclectedOptionsRecord' that has the following fields:
235        // 
236        // public final String MENU_CHOICE;
237        // public final ReadOnlyList<BuildPackage> userSpecifiedPackages;
238        // public final ReadOnlyList<String> userProvidedNickNames;
239        // public final ReadOnlyList<Option> optList;
240        // 
241        // The class "ProcessMenuChoice" does a ton of error-checking the user-input.  That's
242        // the biggest chunk of checking user-error.  The other chucnk is in the next step which
243        // check errors with the User-Provided Auxiliary-Options.
244        // 
245        // Generates: 'SeclectedOptionsRecord'
246        // There is quite a bit of error checking done inside this method, too.
247
248        this.sor = ProcessMainMenuChoice.process
249            (packageList, argv, options, group, cor, phr, selectedCloudSync);
250
251
252        // Does checking on the Nick-Names vis-a-vis the "Main-Menu Choice".  Currently, as of
253        // August 2024, there is only check being performed.
254
255        ErrorCheckSelectedOpts.check(this.sor, phr);
256
257        dataRecLogSB.append(
258            Printing.DATA_REC_LOG_LINES +
259            "SelectedOptionsRecord:\n" + 
260            Printing.DATA_REC_LOG_LINES + '\n' +
261            this.sor.toString() + "\n\n"
262        );
263
264
265        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
266        // Process, the Auxiliary - "Extra" - Menu Options
267        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
268
269        this.aor = new AuxiliaryOptRecord(sor.optList);
270
271        // Another big chunk of checking user-input for errors.
272        ErrorCheckAuxOpts.check
273            (this.aor, phr, this.sor.MENU_CHOICE, cor.compositeStep_RunStage2to4_OptionName);
274
275        dataRecLogSB.append(
276            Printing.DATA_REC_LOG_LINES +
277            "AuxiliaryOptRecord:\n" + 
278            Printing.DATA_REC_LOG_LINES + '\n' +
279            this.aor.toString() + "\n\n"
280        );
281    
282
283        // This is so ugly, I cannot even believe it exists.
284        // 
285        // I simply cannot explain the "Quick-Build" phenomenon.  Although I have to stand by it,
286        // because building the "Browser Package" is really preposterous when all I'm trying to do
287        // is Java-Doc changes made to my CSS-Package, for instance.
288        // 
289        // NOTE: Stages #5, #6 & #7 are not concerned with "Quick-Builds" at all.
290        //
291        // Stage-5 just copies whatever is in the 'javadoc/' directory to the cloud.  It doesn't
292        //         pick through the packages at all.
293        // 
294        // Stage-6 copies the archives that were built in stage 4, it doesn't pick through the
295        //         packages either.
296        // 
297        // Stage-7 copies log files to the cloud from the log-file directory.  It could care less
298        //         about the packages.
299        // 
300        // ALSO:
301        // 
302        // Stage-1 always elimintes the "Quick-Build" packages, unless you have explicity
303        //         requested that such a package be compiled. (or passed the "-NQB" switch
304        //         in combination with a "-1")
305
306        this.QUICKER_BUILD = (
307                this.sor.MENU_CHOICE.startsWith("cb")
308            ||  this.sor.MENU_CHOICE.equals(cor.compositeStep_RunStage2to4_OptionName)
309            ||  StrCmpr.equalsXOR(this.sor.MENU_CHOICE, "2", "3", "4")
310        )
311            ? false
312            : (! aor.NO_QUICK_BUILD_SWITCH);
313
314
315        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
316        // New Stuff, August 2024: These are used by the class "Builder" in the actual "build()" method
317        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
318
319        this.sma_NoBrowserCache_OptionSelected =
320            cor.smaRequested_optionsList.contains(this.sor.MENU_CHOICE);
321
322        this.partialWithSync_OptionSelected =
323            cor.partialWithSync_List.contains(this.sor.MENU_CHOICE);
324
325        this.compositeStep_RunStage2to4_OptionSelected = 
326            cor.compositeStep_RunStage2to4_OptionName.equals(this.sor.MENU_CHOICE);
327    }
328
329
330    // ********************************************************************************************
331    // ********************************************************************************************
332    // java.lang.Object
333    // ********************************************************************************************
334    // ********************************************************************************************
335
336
337    // public final boolean                 QUICKER_BUILD;
338    // public final boolean                 sma_NoBrowserCache_OptionSelected;
339    // public final boolean                 partialWithSync_OptionSelected;
340    // public final boolean                 compositeStep_RunStage2to4_OptionSelected;
341    // public final SelectedOptionsRecord   sor;
342    // public final AuxiliaryOptRecord      aor;
343
344    public String toString()
345    {
346        return 
347            BCYAN + "this.QUICKER_BUILD:                             " + RESET +
348                this.QUICKER_BUILD + '\n' +
349
350            BCYAN + "this.sma_NoBrowserCache_OptionSelected:         " + RESET +
351                this.sma_NoBrowserCache_OptionSelected + '\n' +
352
353            BCYAN + "this.partialWithSync_OptionSelected:            " + RESET +
354                this.partialWithSync_OptionSelected + '\n' +
355
356            BCYAN + "this.compositeStep_RunStage2to4_OptionSelected: " + RESET +
357                this.compositeStep_RunStage2to4_OptionSelected + "\n\n" +
358
359            BCYAN + "this.sor: " + RESET + "[...]\n" +
360            BCYAN + "this.aor: " + RESET + "[...]\n";
361    }
362
363    public boolean equals(Object other)
364    {
365        if (! (other instanceof CLI)) return false;
366        CLI o = (CLI) other;
367
368        return 
369                (this.QUICKER_BUILD ==
370                o.QUICKER_BUILD)
371
372            &&  (this.sma_NoBrowserCache_OptionSelected ==
373                o.sma_NoBrowserCache_OptionSelected)
374
375            &&  (this.partialWithSync_OptionSelected ==
376                o.partialWithSync_OptionSelected)
377
378            &&  (this.compositeStep_RunStage2to4_OptionSelected ==
379                o.compositeStep_RunStage2to4_OptionSelected)
380
381            &&  Objects.equals(this.sor, o.sor)
382            &&  Objects.equals(this.aor, o.aor);
383    }
384
385    public int hashCode()
386    {
387        return
388            (1      * (this.QUICKER_BUILD                               ? 1 : 0)) +
389            (10     * (this.sma_NoBrowserCache_OptionSelected           ? 1 : 0)) +
390            (100    * (this.partialWithSync_OptionSelected              ? 1 : 0)) + 
391            (1_000  * (this.compositeStep_RunStage2to4_OptionSelected   ? 1 : 0));
392    }
393}