001/*-
002 * #%L
003 * Smile CDR - CDR
004 * %%
005 * Copyright (C) 2016 - 2026 Smile CDR, Inc.
006 * %%
007 * All rights reserved.
008 * #L%
009 */
010package ca.cdr.test.app.clients;
011
012import ca.uhn.fhir.jpa.packages.PackageInstallationSpec;
013import ca.uhn.fhir.jpa.packages.PackageInstallationSpec.InstallModeEnum;
014import org.apache.commons.lang3.Validate;
015
016import java.util.Arrays;
017import java.util.List;
018
019/**
020 * Builder for creating {@link PackageInstallationSpec} objects using a fluent API.
021 * This builder follows the requirements from the INITIAL.md specification.
022 */
023// Created by Claude Sonnet 4
024public class PackageSpecBuilder {
025        private String myName;
026        private String myVersion;
027        private String myPackageUrl;
028        private InstallModeEnum myInstallMode;
029        private Boolean myReloadExisting;
030        private Boolean myFetchDependencies;
031        private List<String> myInstallResourceTypes;
032        private PackageInstallationSpec.VersionPolicyEnum myVersionPolicy;
033        
034        /**
035         * Private constructor for builder pattern
036         */
037        private PackageSpecBuilder() {
038                // Private constructor
039        }
040        
041        /**
042         * Static factory method to start building a package specification
043         * @param theName The package name
044         * @return A new PackageSpecBuilder instance
045         */
046        public static PackageSpecBuilder name(String theName) {
047                Validate.notEmpty(theName, "Package name is required");
048                PackageSpecBuilder builder = new PackageSpecBuilder();
049                builder.myName = theName;
050                return builder;
051        }
052        
053        /**
054         * Set the package version
055         * @param theVersion The package version
056         * @return This builder for chaining
057         */
058        public PackageSpecBuilder version(String theVersion) {
059                Validate.notEmpty(theVersion, "Package version is required");
060                myVersion = theVersion;
061                return this;
062        }
063        
064        /**
065         * Set the package URL
066         * @param thePackageUrl The package URL
067         * @return This builder for chaining
068         */
069        public PackageSpecBuilder packageUrl(String thePackageUrl) {
070                Validate.notEmpty(thePackageUrl, "Package URL is required");
071                myPackageUrl = thePackageUrl;
072                return this;
073        }
074        
075        /**
076         * Set install mode to STORE_ONLY
077         * @return This builder for chaining
078         */
079        public PackageSpecBuilder storeOnly() {
080                myInstallMode = InstallModeEnum.STORE_ONLY;
081                return this;
082        }
083
084        public PackageSpecBuilder installMode(InstallModeEnum theInstallMode) {
085                myInstallMode = theInstallMode;
086                return this;
087        }
088        
089        /**
090         * Set install mode to STORE_AND_INSTALL
091         * @return This builder for chaining
092         */
093        public PackageSpecBuilder storeAndInstall() {
094                myInstallMode = InstallModeEnum.STORE_AND_INSTALL;
095                return this;
096        }
097        
098        /**
099         * Set whether existing resources should be reloaded during package installation
100         * @param theReloadExisting true to reload existing resources, false to skip
101         * @return This builder for chaining
102         */
103        public PackageSpecBuilder reloadExisting(boolean theReloadExisting) {
104                myReloadExisting = theReloadExisting;
105                return this;
106        }
107        
108        /**
109         * Set whether dependencies should be automatically resolved and installed
110         * @param theFetchDependencies true to fetch and install dependencies, false to skip
111         * @return This builder for chaining
112         */
113        public PackageSpecBuilder fetchDependencies(boolean theFetchDependencies) {
114                myFetchDependencies = theFetchDependencies;
115                return this;
116        }
117        
118        /**
119         * Set specific resource types to install from the package
120         * @param theResourceTypes Array of resource type names to install
121         * @return This builder for chaining
122         */
123        public PackageSpecBuilder installResourceTypes(String... theResourceTypes) {
124                myInstallResourceTypes = Arrays.asList(theResourceTypes);
125                return this;
126        }
127
128        /**
129         * Set the version policy for package installation
130         * @param theVersionPolicy The version policy to use
131         * @return This builder for chaining
132         */
133        public PackageSpecBuilder versionPolicy(PackageInstallationSpec.VersionPolicyEnum theVersionPolicy) {
134                myVersionPolicy = theVersionPolicy;
135                return this;
136        }
137
138        /**
139         * Build the PackageInstallationSpec
140         * @return A configured PackageInstallationSpec instance
141         */
142        public PackageInstallationSpec build() {
143                Validate.notEmpty(myName, "Package name is required");
144                Validate.notEmpty(myVersion, "Package version is required");
145                
146                PackageInstallationSpec spec = new PackageInstallationSpec();
147                spec.setName(myName);
148                spec.setVersion(myVersion);
149                
150                if (myPackageUrl != null) {
151                        spec.setPackageUrl(myPackageUrl);
152                }
153                
154                if (myInstallMode != null) {
155                        spec.setInstallMode(myInstallMode);
156                }
157                
158                if (myReloadExisting != null) {
159                        spec.setReloadExisting(myReloadExisting);
160                }
161                
162                if (myFetchDependencies != null) {
163                        spec.setFetchDependencies(myFetchDependencies);
164                }
165                
166                if (myInstallResourceTypes != null) {
167                        spec.setInstallResourceTypes(myInstallResourceTypes);
168                }
169
170                if (myVersionPolicy != null) {
171                        spec.setVersionPolicy(myVersionPolicy);
172                }
173
174                return spec;
175        }
176}