// ***************************************************************************************************************************
// * 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.internal;

import static org.apache.juneau.internal.ConverterUtils.*;
import static org.apache.juneau.internal.ExceptionUtils.*;
import static org.apache.juneau.internal.StringUtils.*;

import java.lang.reflect.*;
import java.util.*;

import org.apache.juneau.collections.*;
import org.apache.juneau.parser.*;

/**
 * Builder for lists.
 *
 * @param <E> Element type.
 */
public class ListBuilder<E> {

	private List<E> list;
	private boolean unmodifiable = false, sparse = false;
	private Comparator<E> comparator;

	private Class<E> elementType;
	private Type[] elementTypeArgs;

	/**
	 * Constructor.
	 *
	 * @param elementType The element type.
	 * @param elementTypeArgs The element type generic arguments if there are any.
	 */
	public ListBuilder(Class<E> elementType, Type...elementTypeArgs) {
		this.elementType = elementType;
		this.elementTypeArgs = elementTypeArgs;
	}

	/**
	 * Constructor.
	 *
	 * @param addTo The list to add to.
	 */
	public ListBuilder(List<E> addTo) {
		this.list = addTo;
	}

	/**
	 * Builds the list.
	 *
	 * @return A list conforming to the settings on this builder.
	 */
	public List<E> build() {
		if (sparse) {
			if (list != null && list.isEmpty())
				list = null;
		} else {
			if (list == null)
				list = new ArrayList<>(0);
		}
		if (list != null) {
			if (comparator != null)
				Collections.sort(list, comparator);
			if (unmodifiable)
				list = Collections.unmodifiableList(list);
		}
 		return list;
	}

	/**
	 * When specified, the {@link #build()} method will return <jk>null</jk> if the list is empty.
	 *
	 * <p>
	 * Otherwise {@link #build()} will never return <jk>null</jk>.
	 *
	 * @return This object (for method chaining).
	 */
	public ListBuilder<E> sparse() {
		this.sparse = true;
		return this;
	}

	/**
	 * When specified, {@link #build()} will return an unmodifiable list.
	 *
	 * @return This object (for method chaining).
	 */
	public ListBuilder<E> unmodifiable() {
		this.unmodifiable = true;
		return this;
	}

	/**
	 * Forces the existing list to be copied instead of appended to.
	 *
	 * @return This object (for method chaining).
	 */
	public ListBuilder<E> copy() {
		if (list != null)
			list = new ArrayList<>(list);
		return this;
	}

	/**
	 * Sorts the contents of the list.
	 *
	 * @return This object (for method chaining).
	 */
	@SuppressWarnings("unchecked")
	public ListBuilder<E> sorted() {
		return sorted((Comparator<E>)Comparator.naturalOrder());
	}

	/**
	 * Sorts the contents of the list using the specified comparator.
	 *
	 * @param comparator The comparator to use for sorting.
	 * @return This object (for method chaining).
	 */
	public ListBuilder<E> sorted(Comparator<E> comparator) {
		this.comparator = comparator;
		return this;
	}

	/**
	 * Appends the contents of the specified collection into this list.
	 *
	 * <p>
	 * This is a no-op if the value is <jk>null</jk>.
	 *
	 * @param value The collection to add to this list.
	 * @return This object (for method chaining).
	 */
	public ListBuilder<E> addAll(Collection<E> value) {
		if (value != null) {
			if (list == null)
				list = new LinkedList<>(value);
			else
				list.addAll(value);
		}
		return this;
	}

	/**
	 * Adds a single value to this list.
	 *
	 * @param value The value to add to this list.
	 * @return This object (for method chaining).
	 */
	public ListBuilder<E> add(E value) {
		if (list == null)
			list = new ArrayList<>();
		list.add(value);
		return this;
	}

	/**
	 * Adds multiple values to this list.
	 *
	 * @param values The values to add to this list.
	 * @return This object (for method chaining).
	 */
	@SuppressWarnings("unchecked")
	public ListBuilder<E> add(E...values) {
		for (E v : values)
			add(v);
		return this;
	}

	/**
	 * Adds entries to this list via JSON array strings.
	 *
	 * @param values The JSON array strings to parse and add to this list.
	 * @return This object (for method chaining).
	 */
	public ListBuilder<E> addJson(String...values) {
		return addAny((Object[])values);
	}

	/**
	 * Adds arbitrary values to this list.
	 *
	 * <p>
	 * Objects can be any of the following:
	 * <ul>
	 * 	<li>The same type or convertible to the element type of this list.
	 * 	<li>Collections or arrays of anything on this list.
	 * 	<li>JSON array strings parsed and convertible to the element type of this list.
	 * </ul>
	 *
	 * @param values The values to add.
	 * @return This object (for method chaining).
	 */
	@SuppressWarnings("unchecked")
	public ListBuilder<E> addAny(Object...values) {
		if (elementType == null)
			throw runtimeException("Unknown element type.  Cannot use this method.");
		try {
			if (values != null) {
				for (Object o : values) {
					if (o != null) {
						if (o instanceof Collection) {
							for (Object o2 : (Collection<?>)o)
								addAny(o2);
						} else if (o.getClass().isArray()) {
							for (int i = 0; i < Array.getLength(o); i++)
								addAny(Array.get(o, i));
						} else if (isJsonArray(o, false)) {
							for (Object o2 : new OList(o.toString()))
								addAny(o2);
						} else if (elementType.isInstance(o)) {
							add((E)o);
						} else {
							add(toType(o, elementType, elementTypeArgs));
						}
					}
				}
			}
		} catch (ParseException e) {
			throw runtimeException(e);
		}
		return this;
	}
}
