// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

package jodd.joy;

import jodd.props.Props;
import jodd.props.PropsUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;

public class JoyProps extends JoyBase {
	protected final Supplier<String> nameSupplier;

	protected Props props;

	public JoyProps(final Supplier<String> nameSupplier) {
		this.nameSupplier = nameSupplier;
	}

	// ---------------------------------------------------------------- getters

	/**
	 * Returns application Props.
	 */
	public Props getProps() {
		return props;
	}

	// ---------------------------------------------------------------- config

	private String propsNamePattern;
	private List<String> propsProfiles = new ArrayList<>();

	public JoyProps setPropsNamePattern(final String namePattern) {
		this.propsNamePattern = namePattern;
		return this;
	}

	public JoyProps addPropsProfiles(final String... profiles) {
		Collections.addAll(propsProfiles, profiles);
		return this;
	}

	// ---------------------------------------------------------------- lifecycle

	/**
	 * Creates and loads application props.
	 * It first loads system properties (registered as <code>sys.*</code>)
	 * and then environment properties (registered as <code>env.*</code>).
	 * Finally, props files are read from the classpath. All properties
	 * are loaded using
	 * <p>
	 * If props have been already loaded, does nothing.
	 */
	@Override
	void start() {
		initLogger();

		log.info("PROPS start ----------");

		props = createProps();

		props.loadSystemProperties("sys");
		props.loadEnvironment("env");

		log.info("Loaded sys&env props: " + props.countTotalProperties() + " propertes.");

		props.setActiveProfiles(propsProfiles.toArray(new String[0]));

		String namePattern = propsNamePattern;

		if (namePattern == null) {
			namePattern = "/" + nameSupplier.get() + "*.prop*";
		}

		log.debug("Loading props from classpath: " + namePattern);

		PropsUtil.loadFromClasspath(props, namePattern);

		log.info("Props is ready: " + props.countTotalProperties() + " propertes.");
	}

	/**
	 * Creates new {@link Props} with default configuration.
	 * Empty props will be ignored, and missing macros will be
	 * resolved as empty string.
	 */
	protected Props createProps() {
		final Props props = new Props();
		props.setSkipEmptyProps(true);
		props.setIgnoreMissingMacros(true);
		return props;
	}

	@Override
	void stop() {
		props = null;
	}
}

@@ -2030,22 +2030,28 @@
 private 
+List%3C
 String
+%3E
  propsNa
@@ -2059,16 +2059,37 @@
 ePattern
+s = new ArrayList%3C%3E()
 ;%0A%09priva
@@ -2140,16 +2140,60 @@
 t%3C%3E();%0A%0A
+%09/**%0A%09 * Adds props files or patterns.%0A%09 */%0A
 %09public 
@@ -2205,27 +2205,20 @@
 ops 
-set
+add
 Props
-NamePattern
+File
 (fin
@@ -2265,19 +2265,22 @@
 ePattern
- = 
+s.add(
 namePatt
@@ -2282,16 +2282,17 @@
 ePattern
+)
 ;%0A%09%09retu
@@ -3111,24 +3111,25 @@
  + %22 propert
+i
 es.%22);%0A%0A%09%09pr
@@ -3187,38 +3187,96 @@
 ing%5B
-0%5D));%0A%0A%09%09String nameP
+propsProfiles.size()%5D));%0A%0A%09%09// prepare patterns%0A%0A%09%09final String%5B%5D p
 attern
+s
  = 
+new String%5B
 prop
@@ -3291,54 +3291,37 @@
 tern
-;%0A%0A%09%09if (namePattern == null) %7B%0A%09%09%09nameP
+s.size() + 1%5D;%0A%0A%09%09p
 attern
+s%5B0%5D
  = %22
@@ -3356,16 +3356,119 @@
 .prop*%22;
+%0A%0A%09%09for (int i = 0; i %3C propsNamePatterns.size(); i++) %7B%0A%09%09%09patterns%5Bi + 1%5D = propsNamePatterns.get(i);
 %0A%09%09%7D%0A%0A%09%09
@@ -3510,25 +3510,12 @@
 path
-: %22 + namePattern
+...%22
 );%0A%0A
@@ -3551,27 +3551,24 @@
 (props, 
-nameP
+p
 attern
+s
 );%0A%0A%09%09lo
@@ -3635,16 +3635,17 @@
  propert
+i
 es.%22);%0A%09

Allow many props files to load (closes #593)