001package Torello.Java.Build;
002
003import Torello.Java.ReadOnly.ReadOnlyList;
004import Torello.Java.StrCSV;
005
006import Apache.CLI.Option;
007
008import static Torello.Java.C.BCYAN;
009import static Torello.Java.C.RESET;
010
011import java.util.Objects;
012import java.util.function.Function;
013
014
015/**
016 * This class contains an internally used {@code boolean}-Flag field corresponding to each of the
017 * Auxiliary Command-Line Options / Switches available by this Build-Tool.
018 * 
019 * <!-- Contains the black-banner declaring this is a CLI-group internally used class -->
020 * <EMBED CLASS='external-html' DATA-FILE-ID=CLI_INTERNAL_USE>
021 * 
022 * <!-- Explains how to retrieve an instance of this class, and provides an example -->
023 * <EMBED CLASS='external-html' DATA-FIELDNAME=sor DATA-FILE-ID=CLI_GET_REFERENCE>
024 * 
025 * <BR /><BR />This record is how used to preserve the User's Command-Line input at a higher
026 * level.  The switches that the user has entered are all stored inside this record - except the
027 * switches that correspond to Auxiliary Menu-Options.
028 * 
029 * @see AuxiliaryOptRecord
030 */
031public class SelectedOptionsRecord
032{
033    // These public fields are all available immediately after the class CLI has begun processing
034    // the User's Command-Line Switches.
035    // 
036    // Immediately, the class CLI knows the "MENU_CHOICE" he has selected, and can tell very 
037    // quickly all of the Package Nick-Names that he has entered (if any).
038
039    /**
040     * This field contains the end User-Selected Command-Line Main-Menu Option/Choice (as a 
041     * {@code java.lang.String}).
042     * 
043     * <BR /><BR />Some common examples of routinely passed CLI switches that are ultimately 
044     * assigned to this field include:
045     * 
046     * <BR /><BR /><UL CLASS=JDUL>
047     * <LI> {@code "-1"} - signifying that the {@code 'javac'} Compiler-Stage be run (a.k.a.
048     *      "Please Compile my Files, or <B STYLE='color: red;'><I>some</I></B> of my files").
049     *      <BR /><BR /></LI>
050     * 
051     * <LI> {@code "-cb1"} - requesting that the Composite-Step Option of a "Complete Build" be 
052     *      executed.  All {@code '.java'} Source-Files will be Java-Doc'd, those {@code '.html'}
053     *      Documentation-Pages will be ugraded, and then archived/tar'ed.  Afterwards, the 
054     *      generted {@code '.jar'}-File will be placed on your Domain-Website's Storage-Bucket, as
055     *      will all of your Documentation-Pages for your Source-Code.
056     *      <BR /><BR /></LI>
057     * 
058     * <LI> {@code "-pb1"} - requesting that some subset of packages in your source need to be
059     *      re-compiled, documented, and possibly synchronized to your Cloud Storage Space.
060     *      <BR /><BR /></LI>
061     * 
062     * </UL>
063     * 
064     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
065     */
066    public final String MENU_CHOICE;
067
068    /**
069     * This {@link ReadOnlyList} will, after constructing an instance of this class, contain the
070     * exact list of Java-Packages that have been included in this build.
071     * 
072     * <BR /><BR />Most Build-Options will "Build" all Java Packages provided to the {@link Config}
073     * class' {@link Config#packageList} array.  However, there are a few Main Menu-Options that 
074     * allow for specifying, explicity, which Java Packages are to be included.
075     * 
076     * <BR /><BR />This is another option whose primary use is for speeding up your interactive
077     * "builds".  If documenting your pages is important to you, and re-building and re-publishing
078     * your documentation to your Web-Domain's Storage-Space, then requesting that just a small
079     * sub-set of your packages' {@code '.html'}-Files need to be udating can speed things up
080     * tremendously.
081     * 
082     * <BR /><BR /><B CLASS=JDDescLabel>How it's Used:</B>
083     * 
084     * <BR />Usually, this list will be identical to the list contained in 
085     * {@link BuildPackage}-Array {@link Config#packageList}.  The list of packages contained by
086     * this list will be "abridged", if a list of Package Nick-Names were provided at the 
087     * Command-Line.
088     * 
089     * <BR /><BR />Please review, at the top of this class, precisely which Main Menu-Options
090     * allow for specifying a list of "Package Nick-Names."  It is for those precise Menu Choices
091     * that this particular field will be somewhat shorter than the User-Provided array contained
092     * within class {@link Config} Array-Field {@link Config#packageList}.
093     * 
094     * <BR /><BR /><B CLASS=JDDescLabel>Steps / Stages Affected:</B>
095     * 
096     * <BR /><BR /><UL CLASS=JDUL>
097     * 
098     * <LI> <B>{@link S01_JavaCompiler}</B> - This list is utilized to decide which
099     *      Java-Packages actually need to be compiled by {@code 'javac'}.
100     *      <BR /><BR /></LI>
101     * 
102     * <LI> <B>{@link S03_Upgrade}</B> - Employed to decide which Java-Doc {@code '.html'}-Files
103     *      require upgrading, by the Java-Doc Upgrader.
104     *      <BR /><BR /></LI>
105     * 
106     * <LI> <B>{@link S05_SyncJavaDoc}</B> - Used to decide which {@code '.html'}-Files must be
107     *      re-copied to your Web-Domain's Storage-Bucket directories, so that your Java-Doc based
108     *      Web-Site contains your latest changes.
109     *      <BR /><BR /></LI>
110     * 
111     * </UL>
112     * 
113     * <BR /><BR />Note that many of the stages, (Stage-2, for instance) ignore completely the 
114     * contents of this {@code ReadOnlyList}.  The original {@code 'javadoc'} program will always
115     * rebuild your entire Java-Doc Site, because it is the source of many, many URL-Anchor
116     * ({@code '<A HREF=...>'}) links.
117     * 
118     * <BR /><BR />Furthermore your Archive-Files (your {@code '.jar'} and {@code '.tar'}) files
119     * will never "leave out" any {@code '.class'}-Files or Source-Code.
120     * 
121     * <BR /><BR />The Steps within this Build-Tool that allow for Package Nick-Name's to be passed
122     * at the Command-Line are only their for quickly, and efficiently, upgrading your Java-Doc 
123     * Web-Site so that you may <B STYLE='color: red'><I>quickly</I></B> inspect how your latest
124     * round of changes actually look on the web.
125     * 
126     * <BR /><BR /><BR /><B CLASS=JDDescLabel>How it's Populated:</B>
127     * 
128     * <BR /><DIV CLASS=SNIP>{@code
129     * final ArrayList<String> l = new ArrayList<>();
130     * 
131     * if (nickNamesProvided)
132     *      for (String pkgNickName : nickNames) l.add(pkgNickName);
133     * 
134     * if (EXTRA_PACKAGE_NICKNAMES)
135     *      for (String pkgNickName : extraneousArgs) l.add(pkgNickName);
136     * 
137     * this.userProvidedNickNames = nickNamesProvided
138     *      ? new ReadOnlyArrayList<String>(l)
139     *      : null;
140     * 
141     * this.userSpecifiedPackages = nickNamesProvided
142     *      ? BuildPackage.nickNameArgVPackages(packageList, this.userProvidedNickNames)
143     *      : null;
144     * }</DIV>
145     * 
146     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
147     * 
148     * @see Config#packageList
149     * @see #userProvidedNickNames
150     */
151    public final ReadOnlyList<BuildPackage> userSpecifiedPackages;
152
153    /**
154     * Please see the documentation for the field {@link #userSpecifiedPackages}, since this field
155     * contains nearly identical information.
156     * 
157     * <BR /><BR />This field is populated by extracting the actual User-Provided Nick-Name from
158     * each of the {@link BuildPackage} instances that are stored within the
159     * {@link #userSpecifiedPackages} list.
160     * 
161     * <EMBED CLASS=external-html DATA-FILE-ID=CLI_PUBLIC_FIELD>
162     * @see Config#packageList
163     * @see #userProvidedNickNames
164     */
165    public final ReadOnlyList<String> userProvidedNickNames;
166
167    /**
168     * The Complete-List of all Options / Switches entered at the Command-Line.
169     */
170    public final ReadOnlyList<Option> optList;
171
172    SelectedOptionsRecord(
173            final String                        MENU_CHOICE,
174            final ReadOnlyList<String>          userProvidedNickNames,
175            final ReadOnlyList<BuildPackage>    userSpecifiedPackages,
176            final ReadOnlyList<Option>          optList
177        )
178    {
179        this.MENU_CHOICE            = MENU_CHOICE;
180        this.userProvidedNickNames  = userProvidedNickNames;
181        this.userSpecifiedPackages  = userSpecifiedPackages;
182        this.optList                = optList;
183    }
184
185
186    // ********************************************************************************************
187    // ********************************************************************************************
188    // java.lang.Object (Would JDK-21+ Record do this for me by automatic?)
189    // ********************************************************************************************
190    // ********************************************************************************************
191
192
193    /**
194     * Converts {@code 'this'} instance to a {@code java.lang.String}
195     * @return This class represented as a {@code String}.
196     */
197    public String toString()
198    {
199        final String upnn = (this.userProvidedNickNames != null)
200            ? this.userProvidedNickNames.toString()
201            : "null, meaning none-provided";
202
203        final Function<Option, String> PRINTER = (Option opt) ->
204            "\n\t" + opt.toString();
205
206        return 
207            BCYAN + "this.MENU_CHOICE:            " + RESET + this.MENU_CHOICE + "\n" +
208            BCYAN + "this.userProvidedNickNames:  " + RESET + upnn + "\n" +
209            BCYAN + "this.userSpecifiedPackages:  " + RESET + "[See Above List]\n\n" +
210            BCYAN + "this.optList: " + RESET +
211                "**Apache.CLI.Option instances, toString()-invocation**" +
212                StrCSV.toCSV(this.optList, PRINTER, true, null) + '\n';
213    }
214
215    /**
216     * Check's for equality between {@code 'this'} instance, and any other instance of
217     * {@code java.lang.Object}
218     * 
219     * @param o Any Java Object-Reference.  Only an instance of class {@code SelectedOptionRecord}
220     * will generate a return-value of {@code TRUE}, and particularly only one whose fields are all
221     * equal to the corresponding fields in {@code 'this'} instance.
222     * 
223     * @return {@code TRUE} if and only if {@code 'o'} and {@code 'this'} are equal, as explained
224     * above.
225     */
226    public boolean equals(Object o)
227    {
228        if (! (o instanceof SelectedOptionsRecord)) return false;
229        SelectedOptionsRecord other = (SelectedOptionsRecord) o;
230
231        return
232                Objects.equals(this.MENU_CHOICE, other.MENU_CHOICE)
233            &&  Objects.equals(this.userProvidedNickNames, other.userProvidedNickNames)
234            &&  Objects.equals(this.userSpecifiedPackages, other.userSpecifiedPackages)
235            &&  Objects.equals(this.optList, other.optList);
236    }
237
238    /**
239     * Generates a Hash-Code for use with Standard-Java {@code Hashtable's} etc...
240     * 
241     * @return A (somewhat) unique Hash-Code, to be used for placing an instance of this 
242     * class into any variant of Hash-Table.
243     */
244    public int hashCode()
245    { return this.MENU_CHOICE.hashCode() + this.userProvidedNickNames.hashCode(); }
246}