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
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;

/**
 * Decide which User-Provided Packages will be put through the various Build-Stages.
 */
@Torello.JavaDoc.StaticFunctional
public class Packages
{
    private Packages() { }

    /**
     * Used in the Class {@link Builder}-Constructor to specify, exactly, which packages may or may
     * not be processed during an invocation of that class' {@link Builder#build() build} 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
     * by {@link Builder} 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>
     */
    public static Ret2
        <
            ReadOnlyList<BuildPackage>,
            ReadOnlyList<BuildPackage>
        >
        packagesInThisBuild
        (CLI cli, 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 -cb1
        //         "Complete Build 1" (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.
        //
        // 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.userSpecifiedPackages == null);

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

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

            if (bp.earlyDevelopment)
            {
                if (cli.INCLUDE_EARLY_DEV_PACKAGES) return true;

                return IS_FULL_COMPILE
                    ? false
                    : cli.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 builder 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
     */
    public static ReadOnlyList<BuildPackage> packagesToCompile(Builder builder) 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 = (builder.cli.userSpecifiedPackages == null);

        final Predicate<BuildPackage> FILT = (builder.cli.INCLUDE_EARLY_DEV_PACKAGES)
            ? (BuildPackage bp) -> bp.mustReCompile || bp.earlyDevelopment
            : (BuildPackage bp) -> bp.mustReCompile;

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

        return packagesToCompile;
    }

    /**
     * This determines which packages should be run through {@code 'javadoc'}, in the Stage 2
     * Build-Class {@link S02_JavaDoc}.
     * 
     * @param builder 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.
     */
    public static ReadOnlyList<BuildPackage> packagesToJavaDoc(Builder builder)
    {
        // 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<>
            (builder.packageList, FILT, builder.packageList.size());

        return ret;
    }
}