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
package Torello.Java.Build;

import Torello.Java.ReadOnly.ReadOnlyList;
import Torello.Java.ReadOnly.ReadOnlyArrayList;

import Torello.Java.StringParse;
import Torello.Java.StrCSV;

import Torello.Java.Additional.Ret2;

import java.util.function.Predicate;
import java.io.IOException;

/**
 * This class will accept the User-Provided list of Packages that may be built during a build,
 * and generate a final list of packages that will be processed during any given build - <I>as
 * initiated at the command line by user command</I>.
 * 
 * <BR /><BR />Is a utility used internally by the following Build-Stages:
 *
 * <BR /><BR /><UL CLASS=JDUL>
 * <LI>Class {@link BuilderRecord} Constructor</LI>
 * <LI>Compilation / Stage-1</LI>
 * <LI>Documentation / Java-Doc / Stage-2</LI>
 * </UL>
 * 
 * <BR />
 * <EMBED CLASS='external-html' DATA-FILE-ID=INTERNAL_CLASS_NOTE>
 */
@Torello.JavaDoc.StaticFunctional
public class Packages
{
    private Packages() { }

    /**
     * Used in the Class {@link BuilderRecord}-Constructor to specify, exactly, which packages may
     * or may not be processed during an invocation of the {@link RunBuild#run(BuilderRecord)}
     * method.
     * 
     * @param cli The Object that represents / contains the switches and User-Requests that were
     * obtained at the Command-Line from the Command-Line Parser Object {@link CLI}.
     * 
     * @param usersBuildPackageList The list of {@link BuildPackage} instances that were passed to
     * the User-Configuration Class {@link Config}.  The reference passed to this parameter is the
     * exact same reference that is found in {@link Config#packageList}.
     * 
     * @return This, essentially, returns the exact same input list, but after it has been divided
     * into two sets - those packages that are going to be included in the Build, and any packages
     * that are not part of the build.
     * 
     * <BR /><BR />The packages that are 'removed' from the build are:
     * 
     * <BR /><BR /><UL CLASS=JDUL>
     *
     * <LI> <B>{@link BuildPackage#EARLY_DEVELOPMENT Early-Development} Packages</B>
     *      <BR />These are packages which are not completed yet, and are not ready for
     *      publication &amp; distribution.
     *      <BR /><BR /></LI>
     *
     * <LI> <B>{@link BuildPackage#QUICKER_BUILD_SKIP Skip-On-Quick-Build} Packages</B>
     *      <BR />These are packages which are aren't necessarily imperative for the
     *      proper functioning of JAR, and for speed and a faster development time can be
     *      eliminated from your {@code '.jar'} when focusing on other parts of the build.
     *      </LI>
     *
     * </UL>
     * 
     * <BR /><BR /><B CLASS=JDDescLabel>Inclusion Decisions:</B>
     * 
     * <BR />The decision that remove packages from the list of "Packages to Process
     * in the Build" can be reversed at the Command-Line using the {@code '-NQB'} (No Quick Build)
     * or the {@code '-IEDP'} (Include Early-Development Packages.)
     * 
     * <BR /><BR />Utlimately this method returns two lists, contained by an instance of
     * {@link Ret2}.  The instances of {@link BuildPackage} that are going to be processed during
     * a build are in one list, and the {@code BuildPackage} instances to be skipped are in the
     * second list.
     * 
     * <BR /><BR /><UL CLASS=JDUL>
     * 
     * <LI> <B>{@code Ret2.a: ReadOnlyList<BuildPackage>}</B>
     *      <BR />The list of packages to be processed in this build.
     *      <BR /><BR /></LI>
     * 
     * <LI> <B>{@code Ret2.b: ReadOnlyList<BuildPackage>}</B>
     *      <BR />The list of packages to that are being skipped in this build.
     *      </LI>
     * 
     * </UL>
     */
    static Ret2
        <
            ReadOnlyList<BuildPackage>,
            ReadOnlyList<BuildPackage>
        >
        packagesInThisBuild
        (final CLI cli, final BuildPackage[] usersBuildPackageList)
    {
        // This is a little complicated.  All this is doing is "merging" a suite of User-Provided
        // configurations from about three different places.
        // 
        // The class "BuildPackage" allows the user to configure settings for the packages.  One of
        // those settings allows a user to assert that a package is a "Skip if Quick Build."  In my
        // world all that is talking about is the "Torello.Browser" Package, which:
        //
        //      1) Takes for ever to compile
        //      2) Takes even longer to run the Java-Doc (and even longer for the upgrader)
        //      3) MOST-IMPORTANTLY: Never changes at all, because i'm not working on it right now.
        //         As a result, pretending it doesn't exist, except when compiling with a -cb
        //         "Complete Build" (The actual "Release Directory"), makes working a lot easier
        //
        // Class CLI also allows users to configure stuff by passing switches.  It's mechanisms
        // involve arguments passed to the "String[] argv" parameter via the
        // "public static void main" method. 
        // 
        // Class 'Config' allows a user to provide configurations too, and the user's choice for a
        // CloudSync list does, indeed, affect one minor part of this method, the name of the main
        // menu option switch for Composite-Step Buid's for Steps #1 to #4 (a specific/particular 
        // choice that's provided at the Main-Menu).  When this one is selected, it is possible for
        // a Partial-Build to actually require the Quick-Build stuff to be included, rather than 
        // being eliminated!
        // 
        // The field CLI.QUICKER_BUILD is a boolean that's computed inside the class CLI
        // Constructor.  If you go look at it, it's kind of simple.  Any time a user has selected a
        // "Complete-Build" Menu-Option at the Command-Line, the field CLI.QUICKER_BUILD is
        // guaranteed to be FALSE.
        // 
        // If the User has selected a "Partial-Build", the CLI Field "QUICKER_BUILD" is guaranteed
        // to be TRUE (since that's the whole point of a Package which was assigned "Skip on Quick
        // Build" ==> Specifically Partial-Build's are "Developer-Builds", where the programmer is
        // currently focusing on something totally different, and doesn't want his Command-Line
        // Build to waste a bunch of time on a giant-package which is completely irrelevant and
        // hasn't changed at all in months).
        // 
        // NOTE, on the off-chance that the user selected a Partial-Build that performs, precisely,
        // steps #1 to #4, then the CLI-Field "QUICKER_BUILD" will also be assigned false.  This is
        // becasue Step-4 / Stage-4 is the Archive "Tar & Jar" step, and packages CAN NEVER BE
        // ELIMINATED FROM THE ARCHIVE FILES.  (Their documentation pages are skipped when copying
        // their '.html' Files to the Web-Site, which can speed up a build be at least a minute).
        // 
        // A minute is a lot of time when you are running this stuff over and over and over.
        //
        // In Java-HTML, as of March 2024, the CSS Tokenizer (which is going to have extremely
        // limited use, since "parsing CSS" is several orders of magnitude less useful than parsing
        // HTML) - ... the "CSS Tokenizer" is an "Early Development" package.  Early Development
        // packages have almost the same behavior, they are left out completely (just like the
        // Quick-Build packages) - except when they are explicity requested.
        // 
        // ========================================================================================
        // NOTE: "QUICK_BUILD" and "EARLY_DEVELOPMENT" packages are treated as if they just don't
        //       exist, unless the user has made specific requests for them at the command line CLI
        // ========================================================================================
        // 
        // If a package isn't going to be processed during the build, it is placed into Ret2.b

        final boolean IS_FULL_COMPILE = (cli.sor.userSpecifiedPackages == null);

        final Predicate<BuildPackage> FILT = (BuildPackage bp) ->
        {
            if (cli.QUICKER_BUILD) if (bp.skipIfQuickerBuild)

                return IS_FULL_COMPILE
                    ? false
                    : cli.sor.userSpecifiedPackages.contains(bp);

            if (bp.earlyDevelopment)
            {
                if (cli.aor.INCLUDE_EARLY_DEV_PACKAGES_SWITCH) return true;

                return IS_FULL_COMPILE
                    ? false
                    : cli.sor.userSpecifiedPackages.contains(bp);
            }

            return true;
        };

        final ReadOnlyArrayList<BuildPackage> packagesIncluded =
            new ReadOnlyArrayList<BuildPackage>(FILT, usersBuildPackageList);

        final ReadOnlyArrayList<BuildPackage> packagesEliminated = 
            new ReadOnlyArrayList<BuildPackage>(FILT.negate(), usersBuildPackageList);

        return new Ret2<>(packagesIncluded, packagesEliminated);
    }

    /**
     * This determines which packages should be re-compiled in the Stage 1 Build-Class
     * {@link S01_JavaCompiler}.
     * 
     * @param brec This instance contains all information obtained from the User via the
     * User-Settings class {@link Config}, and information obtained via the Command-Line
     * Interface {@link CLI}.
     * 
     * @return The list of packages whose files are to be recompiled, based on the User-Settings
     * provided class {@link Config}, and the User-Request that were made at the {@link CLI}, 
     * Command-Line Interface
     */
    static ReadOnlyList<BuildPackage> packagesToCompile(final BuilderRecord brec)
        throws IOException
    {
        // It is important to "get" the BuildPackage Configuration-Flags.  
        //
        // The value of BuildPackge.mustReCompile is defined in (surprise) class BuildPackage, as
        // follows, here:
        //
        // this.earlyDevelopment   = (flags & EARLY_DEVELOPMENT) >= 1;
        // this.skipIfQuickerBuild = (flags & QUICKER_BUILD_SKIP)  >= 1;
        // 
        // this.mustReCompile =
        //         (! this.earlyDevelopment)
        //     &&  (! this.skipIfQuickerBuild)
        //     &&  ((flags & DO_NOT_RECOMPILE) == 0); // == 0 implies the "NOT" of the flag
        //
        // FINALLY: The cli.userSpecifiedPackages is literally just the Package-NickNames tht are
        //          provided to class CLI via the "public static void main" method that gets it.

        final boolean IS_FULL_COMPILE = (brec.cli.sor.userSpecifiedPackages == null);

        final Predicate<BuildPackage> FILT = (brec.cli.aor.INCLUDE_EARLY_DEV_PACKAGES_SWITCH)
            ? (BuildPackage bp) -> bp.mustReCompile || bp.earlyDevelopment
            : (BuildPackage bp) -> bp.mustReCompile;

        final ReadOnlyList<BuildPackage> packagesToCompile = IS_FULL_COMPILE
            ? new ReadOnlyArrayList<>(brec.packageList, FILT, brec.packageList.size())
            : brec.cli.sor.userSpecifiedPackages;

        return packagesToCompile;
    }

    /**
     * This determines which packages should be run through {@code 'javadoc'}, in the Stage 2
     * Build-Class {@link S02_JavaDoc}.
     * 
     * @param brec This instance contains all information obtained from the User via the
     * User-Settings class {@link Config}, and information obtained via the Command-Line
     * Interface {@link CLI}.
     * 
     * @return The list of packages whose files are to be sent to the {@code javadoc} Tool, based
     * on the User-Settings provided class {@link Config}, and the User-Request that were made at
     * the {@link CLI}, Command-Line Interface.
     */
    static ReadOnlyList<BuildPackage> packagesToJavaDoc(final BuilderRecord brec)
    {
        // Copied from the class `BuildPackage
        //
        // this.mustDocument        = (flags & DO_NOT_DOCUMENT)     == 0; // The "NOT" of the flag
        // this.earlyDevelopment    = (flags & EARLY_DEVELOPMENT)   >= 1;
        // this.skipIfQuickerBuild  = (flags & QUICKER_BUILD_SKIP)  >= 1;

        final Predicate<BuildPackage> FILT = (BuildPackage pkg) -> pkg.mustDocument;

        final ReadOnlyList<BuildPackage> ret = new ReadOnlyArrayList<>
            (brec.packageList, FILT, brec.packageList.size());

        return ret;
    }
}