1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
package Torello.Java.Build;

import Apache.CLI.Options;
import Apache.CLI.OptionGroup;

import Torello.Java.UnreachableError;
import Torello.Java.StrCmpr;

import Torello.Java.ReadOnly.ReadOnlyList;

import Torello.Java.Additional.ByRef;
import Torello.Java.Additional.Ret4;

import static Torello.Java.C.BCYAN;
import static Torello.Java.C.RESET;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * This data class is instantiated by parsing the Command-Line Input.  It contains the settings
 * that were extrapolated by the Apache CLI Parser. 
 * 
 * <!-- Contains the black-banner declaring this is a CLI-group internally used class -->
 * <EMBED CLASS='external-html' DATA-FILE-ID=CLI_INTERNAL_USE>
 * 
 * <BR /><B CLASS=JDDescLabel>Retrieving an Instance:</B>
 * 
 * <BR />With the above provided notice, if you still wish to view the contents of this class, the
 * Object-Reference that is used by {@link RunBuild} is one of the myriad field's that are made
 * available within the class {@link BuilderRecord}.
 * 
 * <BR /><BR />A {@link BuilderRecord} instance is generated as follows, and the {@code CLI} 
 * instance is obtained by referencing the field {@link BuilderRecord#cli cli}, as below:
 * 
 * <DIV CLASS=EXAMPLE>{@code
 * public static void main(String[] argv)
 * {
 *      Config config = new Config();
 * 
 *      // Perform as many assignments to the Configuration-Fields as is necessary!
 *      // ... [Configurations Here] ...
 *      //see class Config to learn about all available Config-Fields]
 * 
 *      BuilderRecord brec = config.createBuilder(argv);
 * 
 *      // Print's out the contents of this class...
 *      System.out.println(brec.cli);
 * 
 *      // Run's the Build, using all User-Provided Configurations obtained from class Config,
 *      // along with all User-Specified Options provided at the OS Command-Prompt
 * 
 *      RunBuild.run(brec);
 * }
 * }</DIV>
 * 
 * <BR /><BR />The datum contained as fields of this class are all declared {@code public} and also
 * {@code ReadOnly} or {@code final}.  The instance generated from the Command-Line Input (CLI)
 * parser is available as a {@code public} and {@code final} field of the {@link BuilderRecord}
 * instance field {@link BuilderRecord#cli};
 * 
 * <BR /><BR />This class does not offer any public constructors, nor any public methods.  It is 
 * automatically built by class {@code Builder}, which has package-level access to this class' sole
 * constructor.
 * 
 * <EMBED CLASS='external-html' DATA-FILE-ID=CLI_MENU>
 * <EMBED CLASS='external-html' DATA-FILE-ID=CLI_SWITCHES>
 */
public class CLI
{
    // ********************************************************************************************
    // ********************************************************************************************
    // Fields
    // ********************************************************************************************
    // ********************************************************************************************


    /**
     * To-Do: Create a detailed explanation of this sick little bugger.
     * 
     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
     * @see BuildPackage#QUICKER_BUILD_SKIP
     */
    public final boolean QUICKER_BUILD;

    /**
     * There is a way to request that your {@code '.html'}-Files have Meta-Data inside their
     * File-Headers stating that they <B STYLE='color: red;'>do not wish</B> the user's Web-Browser
     * to Cache their Java-Doc {@codde '.html'}-Files.
     * 
     * <BR /><BR />If you are including documentation pages as a part of your Build-Process, then
     * "re-uploading" your Java-Doc {@code '.html'} Pages will be as important as re-compiling and
     * testing your code.
     * 
     * <BR /><BR />If you are intending to visit, and re-visit a particular Web-Address in whatever
     * browser you are using to view your Java-Doc output, then making sure that
     * <B STYLE='color: red'><I>your browser does not cache your Web-Pages</I></B> will save you an
     * endless amount of head-ache.
     * 
     * <BR /><BR />Wiping your Google Chrome's Cache manually can be a real disaster when your
     * saved Form-Field answers are erased, along with your saved Search-Requests or even your
     * passwords!
     * 
     * <BR /><BR /><B CLASS=JDDescLabel>How it's Used:</B>
     * 
     * <BR />This field is manually populated by the internal CLI-Option Building-Class.  All that 
     * is occuring is that, internally, a list of class {@link CLI} Main-Menu Options which
     * indicate / necessitate that <B STYLE='color: red'>Stage 8, Set Max Age</B> was entered, by
     * the user, at the command line.
     * 
     * <BR /><BR />If the User-Selected {@link SelectedOptionsRecord#MENU_CHOICE MENU_CHOICE} is
     * among the known Stage-8 options, then this field will contain {@code TRUE}.
     * 
     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
     */
    public final boolean sma_NoBrowserCache_OptionSelected;

    /**
     * This field is assigned {@code TRUE} when a "Partial Build"
     * {@link SelectedOptionsRecord#MENU_CHOICE MENU_CHOICE} has been selected by the user, at the
     * Command-Line, and that choice is one of the choices that requests Step / Stage 5
     * (Synchronize all {@code '.html'} Files) be run.
     * 
     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
     */
    public final boolean partialWithSync_OptionSelected;

    /**
     * This field is assigned {@code TRUE} if-and-only-if the Composite-Step Menu-Option
     * associated with running Primary-Steps / Primary-Stages #1 to #4 has been selected by the
     * user.
     * 
     * <BR /><BR />This boolean is required by the {@link RunBuild} class in order to decide
     * whether or not to run the Stage-4 (Archive / Tar / Jar) Process for a Composite-Build.
     * 
     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
     * 
     * @see RunBuild#run(BuilderRecord)
     */
    public final boolean compositeStep_RunStage2to4_OptionSelected;

    /**
     * This record is generated based on the Terminal-Input from {@code 'String[] argv'}.
     * 
     * <BR /><BR />As soon as the Apache-CLI Options are generated, they are compared against the
     * User's {@code String[] argv} input, and this record is created.
     */
    public final SelectedOptionsRecord sor;

    /**
     * This Record contains exactly 7 {@code final-boolean} fields, each of which corresponds to
     * exactly one of the available Command-Line Terminal Main-Menu Auxialiary-option Switches.
     * 
     * <BR /><BR />Whenever a user passes a Command-Line Auxiliary Option / Switch at to the
     * {@code String[] argv} parameter, it will be reflected inside this {@code final} class.
     * 
     * @see ErrorCheckAuxOpts
     */
    public final AuxiliaryOptRecord aor;


    // ********************************************************************************************
    // ********************************************************************************************
    // Process the Command-Line Arguments
    // ********************************************************************************************
    // ********************************************************************************************


    CLI(
            final ReadOnlyList<CloudSync>       cloudSyncList,
            final ReadOnlyList<BuildPackage>    packageList,
            final String[]                      argv,
            final ByRef<CloudSync>              selectedCloudSync,  // Return-By-Reference Wrapper
            final StringBuilder                 dataRecLogSB
        )
    {
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Generate an Apache.CLI.Options instance
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        //
        // class 'OptionRecord' contains / creates a list of Apache-CLI Options.
        // 
        // While creating these classes, the calculations produce interim values that are saved.
        // These saved values are then re-used and inserted into the fields...  These are all of
        // the fields contained in the "OptionsRecord"
        // 
        // r4.a: Apache.CLI.Options
        // r4.b: Apache.CLI.OptionGroup
        // r4.c: CollatedOptsRecord
        // r4.d: PrintHelpRecord
        // 
        // CollatedOptsRecord Contents:
        // 
        // public final ReadOnlyList<String> optionsWhichAcceptPkgNickNames;
        // public final ReadOnlyMap<String, CloudSync> cloudSyncSwitchMapper;
        // public final ReadOnlyList<String> smaRequested_optionsList;
        // public final ReadOnlyList<String> partialWithSync_List;
        // public final String compositeStep_RunStage2to4_OptionName;
        // 
        // These records are "ephemeral" or short-lived.  After this class constructor is finished,
        // these records can be cleaned by the Java Garbag-Collector.
        // 
        // These records are, literally, only used inside this constructor for processing the
        // User's Command-Line Input (String[] argv parameter) against the contents of his 
        // Configurations - package-list (of Java-Packages), and CloudSync-List (of Cloud Storage
        // Bucket destinations / targets).

        Ret4<Options, OptionGroup, CollatedOptsRecord, PrintHelpRecord> r4 =
            Generate.generate(cloudSyncList);

        final Options               options = r4.a; // Apache.CLI.Options
        final OptionGroup           group   = r4.b; // Apache.CLI.OptionsGroup
        final CollatedOptsRecord    cor     = r4.c; // Torello.Java.Build.CollatedOptRecord
        final PrintHelpRecord       phr     = r4.d; // Torello.Java.Build.PrintHelpRecord

        dataRecLogSB.append(
            Printing.DATA_REC_LOG_LINES +
            "CollatedOptsRecord:\n" + 
            Printing.DATA_REC_LOG_LINES + '\n' +
            cor.toString() + "\n\n" +

            Printing.DATA_REC_LOG_LINES +
            "PrintHelpRecord:\n" + 
            Printing.DATA_REC_LOG_LINES + '\n' +
            phr.toString() + "\n\n"
        );


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Process, and Error-Check, the Main-Menu Choice
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        //
        // This Class/Method Generates a 'SeclectedOptionsRecord' that has the following fields:
        // 
        // public final String MENU_CHOICE;
        // public final ReadOnlyList<BuildPackage> userSpecifiedPackages;
        // public final ReadOnlyList<String> userProvidedNickNames;
        // public final ReadOnlyList<Option> optList;
        // 
        // The class "ProcessMenuChoice" does a ton of error-checking the user-input.  That's
        // the biggest chunk of checking user-error.  The other chucnk is in the next step which
        // check errors with the User-Provided Auxiliary-Options.
        // 
        // Generates: 'SeclectedOptionsRecord'
        // There is quite a bit of error checking done inside this method, too.

        this.sor = ProcessMainMenuChoice.process
            (packageList, argv, options, group, cor, phr, selectedCloudSync);


        // Does checking on the Nick-Names vis-a-vis the "Main-Menu Choice".  Currently, as of
        // August 2024, there is only check being performed.

        ErrorCheckSelectedOpts.check(this.sor, phr);

        dataRecLogSB.append(
            Printing.DATA_REC_LOG_LINES +
            "SelectedOptionsRecord:\n" + 
            Printing.DATA_REC_LOG_LINES + '\n' +
            this.sor.toString() + "\n\n"
        );


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Process, the Auxiliary - "Extra" - Menu Options
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        this.aor = new AuxiliaryOptRecord(sor.optList);

        // Another big chunk of checking user-input for errors.
        ErrorCheckAuxOpts.check
            (this.aor, phr, this.sor.MENU_CHOICE, cor.compositeStep_RunStage2to4_OptionName);

        dataRecLogSB.append(
            Printing.DATA_REC_LOG_LINES +
            "AuxiliaryOptRecord:\n" + 
            Printing.DATA_REC_LOG_LINES + '\n' +
            this.aor.toString() + "\n\n"
        );
    

        // This is so ugly, I cannot even believe it exists.
        // 
        // I simply cannot explain the "Quick-Build" phenomenon.  Although I have to stand by it,
        // because building the "Browser Package" is really preposterous when all I'm trying to do
        // is Java-Doc changes made to my CSS-Package, for instance.
        // 
        // NOTE: Stages #5, #6 & #7 are not concerned with "Quick-Builds" at all.
        //
        // Stage-5 just copies whatever is in the 'javadoc/' directory to the cloud.  It doesn't
        //         pick through the packages at all.
        // 
        // Stage-6 copies the archives that were built in stage 4, it doesn't pick through the
        //         packages either.
        // 
        // Stage-7 copies log files to the cloud from the log-file directory.  It could care less
        //         about the packages.
        // 
        // ALSO:
        // 
        // Stage-1 always elimintes the "Quick-Build" packages, unless you have explicity
        //         requested that such a package be compiled. (or passed the "-NQB" switch
        //         in combination with a "-1")

        this.QUICKER_BUILD = (
                this.sor.MENU_CHOICE.startsWith("cb")
            ||  this.sor.MENU_CHOICE.equals(cor.compositeStep_RunStage2to4_OptionName)
            ||  StrCmpr.equalsXOR(this.sor.MENU_CHOICE, "2", "3", "4")
        )
            ? false
            : (! aor.NO_QUICK_BUILD_SWITCH);


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // New Stuff, August 2024: These are used by the class "Builder" in the actual "build()" method
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        this.sma_NoBrowserCache_OptionSelected =
            cor.smaRequested_optionsList.contains(this.sor.MENU_CHOICE);

        this.partialWithSync_OptionSelected =
            cor.partialWithSync_List.contains(this.sor.MENU_CHOICE);

        this.compositeStep_RunStage2to4_OptionSelected = 
            cor.compositeStep_RunStage2to4_OptionName.equals(this.sor.MENU_CHOICE);
    }


    // ********************************************************************************************
    // ********************************************************************************************
    // java.lang.Object
    // ********************************************************************************************
    // ********************************************************************************************


    // public final boolean                 QUICKER_BUILD;
    // public final boolean                 sma_NoBrowserCache_OptionSelected;
    // public final boolean                 partialWithSync_OptionSelected;
    // public final boolean                 compositeStep_RunStage2to4_OptionSelected;
    // public final SelectedOptionsRecord   sor;
    // public final AuxiliaryOptRecord      aor;

    public String toString()
    {
        return 
            BCYAN + "this.QUICKER_BUILD:                             " + RESET +
                this.QUICKER_BUILD + '\n' +

            BCYAN + "this.sma_NoBrowserCache_OptionSelected:         " + RESET +
                this.sma_NoBrowserCache_OptionSelected + '\n' +

            BCYAN + "this.partialWithSync_OptionSelected:            " + RESET +
                this.partialWithSync_OptionSelected + '\n' +

            BCYAN + "this.compositeStep_RunStage2to4_OptionSelected: " + RESET +
                this.compositeStep_RunStage2to4_OptionSelected + "\n\n" +

            BCYAN + "this.sor: " + RESET + "[...]\n" +
            BCYAN + "this.aor: " + RESET + "[...]\n";
    }

    public boolean equals(Object other)
    {
        if (! (other instanceof CLI)) return false;
        CLI o = (CLI) other;

        return 
                (this.QUICKER_BUILD ==
                o.QUICKER_BUILD)

            &&  (this.sma_NoBrowserCache_OptionSelected ==
                o.sma_NoBrowserCache_OptionSelected)

            &&  (this.partialWithSync_OptionSelected ==
                o.partialWithSync_OptionSelected)

            &&  (this.compositeStep_RunStage2to4_OptionSelected ==
                o.compositeStep_RunStage2to4_OptionSelected)

            &&  Objects.equals(this.sor, o.sor)
            &&  Objects.equals(this.aor, o.aor);
    }

    public int hashCode()
    {
        return
            (1      * (this.QUICKER_BUILD                               ? 1 : 0)) +
            (10     * (this.sma_NoBrowserCache_OptionSelected           ? 1 : 0)) +
            (100    * (this.partialWithSync_OptionSelected              ? 1 : 0)) + 
            (1_000  * (this.compositeStep_RunStage2to4_OptionSelected   ? 1 : 0));
    }
}