// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.utils;

import java.lang.reflect.*;

import org.apache.juneau.ExecutableException;

/**
 * Utility class for merging POJOs behind a single interface.
 *
 * <p>
 * Useful in cases where you want to define beans with 'default' values.
 *
 * <p>
 * For example, given the following bean classes...
 *
 * <p class='bcode w800'>
 * 	<jk>public interface</jk> IA {
 * 		String getX();
 * 		<jk>void</jk> setX(String x);
 * 	}
 *
 * 	<jk>public class</jk> A <jk>implements</jk> IA {
 * 		<jk>private</jk> String <jf>x</jf>;
 *
 * 		<jk>public</jk> A(String x) {
 * 			<jk>this</jk>.<jf>x</jf> = x;
 * 		}
 *
 * 		<jk>public</jk> String getX() {
 * 			<jk>return</jk> <jf>x</jf>;
 * 		}
 *
 * 		<jk>public void</jk> setX(String x) {
 * 			<jk>this</jk>.<jf>x</jf> = x;
 * 		}
 * 	}
 * </p>
 *
 * <p>
 * The getters will be called in order until the first non-null value is returned...
 *
 * <p class='bcode w800'>
 * 	PojoMerge m;
 *
 * 	m = PojoMerge.<jsm>merge</jsm>(IA.<jk>class</jk>, <jk>new</jk> A(<js>"1"</js>), <jk>new</jk> A(<js>"2"</js>));
 * 	<jsm>assertEquals</jsm>(<js>"1"</js>, m.getX());
 *
 * 	m = PojoMerge.<jsm>merge</jsm>(IA.<jk>class</jk>, <jk>new</jk> A(<jk>null</jk>), <jk>new</jk> A(<js>"2"</js>));
 * 	<jsm>assertEquals</jsm>(<js>"2"</js>, m.getX());
 *
 * 	m = PojoMerge.<jsm>merge</jsm>(IA.<jk>class</jk>, <jk>new</jk> A(<jk>null</jk>), <jk>new</jk> A(<jk>null</jk>));
 * 	<jsm>assertEquals</jsm>(<jk>null</jk>, m.getX());
 * </p>
 *
 * <ul class='notes'>
 * 	<li>
 * 		Null POJOs are ignored.
 * 	<li>
 * 		Non-getter methods are either invoked on the first POJO or all POJOs depending on the <c>callAllNonGetters</c> flag
 * 		passed into the constructor.
 * 	<li>
 * 		For purposes of this interface, a getter is any method with zero arguments and a non-<c>void</c> return type.
 * </ul>
 */
public class PojoMerge {

	/**
	 * Create a proxy interface on top of zero or more POJOs.
	 *
	 * <p>
	 * This is a shortcut to calling <code>merge(interfaceClass, <jk>false</jk>, pojos);</code>
	 *
	 * @param interfaceClass The common interface class.
	 * @param pojos
	 * 	Zero or more POJOs to merge.
	 * 	<br>Can contain nulls.
	 * @return A proxy interface over the merged POJOs.
	 */
	@SuppressWarnings("unchecked")
	public static <T> T merge(Class<T> interfaceClass, T...pojos) {
		return merge(interfaceClass, false, pojos);
	}

	/**
	 * Create a proxy interface on top of zero or more POJOs.
	 *
	 * @param interfaceClass The common interface class.
	 * @param callAllNonGetters
	 * 	If <jk>true</jk>, when calling a method that's not a getter, the method will be invoked on all POJOs.
	 * 	<br>Otherwise, the method will only be called on the first POJO.
	 * @param pojos
	 * 	Zero or more POJOs to merge.
	 * 	<br>Can contain nulls.
	 * @return A proxy interface over the merged POJOs.
	 */
	@SuppressWarnings("unchecked")
	public static <T> T merge(Class<T> interfaceClass, boolean callAllNonGetters, T...pojos) {
		return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[] { interfaceClass }, new PojoMergeInvocationHandler(callAllNonGetters, pojos));
	}

	private static class PojoMergeInvocationHandler implements InvocationHandler {
		private final Object[] pojos;
		private final boolean callAllNonGetters;

		public PojoMergeInvocationHandler(boolean callAllNonGetters, Object...pojos) {
			this.callAllNonGetters = callAllNonGetters;
			this.pojos = pojos;
		}

		/**
		 * Implemented to handle the method called.
	 * @throws ExecutableException Exception occurred on invoked constructor/method/field.
		 */
		@Override /* InvocationHandler */
		public Object invoke(Object proxy, Method method, Object[] args) throws ExecutableException {
			Object r = null;
			boolean isGetter = args == null && method.getReturnType() != Void.class;
			for (Object pojo : pojos) {
				if (pojo != null) {
					try {
						r = method.invoke(pojo, args);
					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
						throw new ExecutableException(e);
					}
					if (isGetter) {
						if (r != null)
							return r;
					} else {
						if (! callAllNonGetters)
							return r;
					}
				}
			}
			return r;
		}
	}
}
