001/*-
002 * #%L
003 * Smile CDR - CDR
004 * %%
005 * Copyright (C) 2016 - 2025 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        
033        /**
034         * Private constructor for builder pattern
035         */
036        private PackageSpecBuilder() {
037                // Private constructor
038        }
039        
040        /**
041         * Static factory method to start building a package specification
042         * @param theName The package name
043         * @return A new PackageSpecBuilder instance
044         */
045        public static PackageSpecBuilder name(String theName) {
046                Validate.notEmpty(theName, "Package name is required");
047                PackageSpecBuilder builder = new PackageSpecBuilder();
048                builder.myName = theName;
049                return builder;
050        }
051        
052        /**
053         * Set the package version
054         * @param theVersion The package version
055         * @return This builder for chaining
056         */
057        public PackageSpecBuilder version(String theVersion) {
058                Validate.notEmpty(theVersion, "Package version is required");
059                myVersion = theVersion;
060                return this;
061        }
062        
063        /**
064         * Set the package URL
065         * @param thePackageUrl The package URL
066         * @return This builder for chaining
067         */
068        public PackageSpecBuilder packageUrl(String thePackageUrl) {
069                Validate.notEmpty(thePackageUrl, "Package URL is required");
070                myPackageUrl = thePackageUrl;
071                return this;
072        }
073        
074        /**
075         * Set install mode to STORE_ONLY
076         * @return This builder for chaining
077         */
078        public PackageSpecBuilder storeOnly() {
079                myInstallMode = InstallModeEnum.STORE_ONLY;
080                return this;
081        }
082
083        public PackageSpecBuilder installMode(InstallModeEnum theInstallMode) {
084                myInstallMode = theInstallMode;
085                return this;
086        }
087        
088        /**
089         * Set install mode to STORE_AND_INSTALL
090         * @return This builder for chaining
091         */
092        public PackageSpecBuilder storeAndInstall() {
093                myInstallMode = InstallModeEnum.STORE_AND_INSTALL;
094                return this;
095        }
096        
097        /**
098         * Set whether existing resources should be reloaded during package installation
099         * @param theReloadExisting true to reload existing resources, false to skip
100         * @return This builder for chaining
101         */
102        public PackageSpecBuilder reloadExisting(boolean theReloadExisting) {
103                myReloadExisting = theReloadExisting;
104                return this;
105        }
106        
107        /**
108         * Set whether dependencies should be automatically resolved and installed
109         * @param theFetchDependencies true to fetch and install dependencies, false to skip
110         * @return This builder for chaining
111         */
112        public PackageSpecBuilder fetchDependencies(boolean theFetchDependencies) {
113                myFetchDependencies = theFetchDependencies;
114                return this;
115        }
116        
117        /**
118         * Set specific resource types to install from the package
119         * @param theResourceTypes Array of resource type names to install
120         * @return This builder for chaining
121         */
122        public PackageSpecBuilder installResourceTypes(String... theResourceTypes) {
123                myInstallResourceTypes = Arrays.asList(theResourceTypes);
124                return this;
125        }
126        
127        /**
128         * Build the PackageInstallationSpec
129         * @return A configured PackageInstallationSpec instance
130         */
131        public PackageInstallationSpec build() {
132                Validate.notEmpty(myName, "Package name is required");
133                Validate.notEmpty(myVersion, "Package version is required");
134                
135                PackageInstallationSpec spec = new PackageInstallationSpec();
136                spec.setName(myName);
137                spec.setVersion(myVersion);
138                
139                if (myPackageUrl != null) {
140                        spec.setPackageUrl(myPackageUrl);
141                }
142                
143                if (myInstallMode != null) {
144                        spec.setInstallMode(myInstallMode);
145                }
146                
147                if (myReloadExisting != null) {
148                        spec.setReloadExisting(myReloadExisting);
149                }
150                
151                if (myFetchDependencies != null) {
152                        spec.setFetchDependencies(myFetchDependencies);
153                }
154                
155                if (myInstallResourceTypes != null) {
156                        spec.setInstallResourceTypes(myInstallResourceTypes);
157                }
158                
159                return spec;
160        }
161}