/*=============================================================================#
 # Copyright (c) 2015, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.jcommons.lang;

import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.FIELD;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.PARAMETER;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.RETURN_TYPE;

import java.util.Collection;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;
import java.util.function.Supplier;


@NonNullByDefault({ PARAMETER, RETURN_TYPE, FIELD })
public final class ObjectUtils {
	
	
	public static class ToStringBuilder {
		
		
		private static final String INDENT= "  "; //$NON-NLS-1$
		private static final String CONT_INDENT= INDENT + INDENT;
		
		private static final String LINE_PREFIX= "\n";
		private static final String PROP_PREFIX= LINE_PREFIX + INDENT;
		private static final String PROP_ASSIGN= "= "; //$NON-NLS-1$
		
		private static final Object NULL= "<null>"; //$NON-NLS-1$
		
		
		private final StringBuilder sb;
		
		private @Nullable Formatter formatter;
		
		
		public ToStringBuilder() {
			this.sb= new StringBuilder();
		}
		
		public ToStringBuilder(final String name) {
			this.sb= new StringBuilder(name);
		}
		
		public ToStringBuilder(final String name, final Class<?> clazz) {
			this.sb= new StringBuilder(name);
			
			this.sb.append(" ("); //$NON-NLS-1$
			this.sb.append(clazz.getName());
			this.sb.append(")"); //$NON-NLS-1$
		}
		
		public ToStringBuilder(final Class<?> defClazz, final Class<?> clazz) {
			this(defClazz.getSimpleName(), clazz);
		}
		
		public ToStringBuilder(final Class<?> defClazz) {
			this(defClazz.getSimpleName());
		}
		
		
		public StringBuilder getStringBuilder() {
			return this.sb;
		}
		
		public final void append(final String s) {
			this.sb.append(s);
		}
		
		public final void append(final String s, final int begin, final int end) {
			this.sb.append(s, begin, end);
		}
		
		public final void append(final char c) {
			this.sb.append(c);
		}
		
		public final void append(final int number) {
			this.sb.append(number);
		}
		
		public final void append(final long number) {
			this.sb.append(number);
		}
		
		public final void append(final char sep, final String s) {
			this.sb.append(sep);
			this.sb.append(s);
		}
		
		public final void append(final char sep, final int number) {
			this.sb.append(sep);
			this.sb.append(number);
		}
		
		public final void append(final char sep, final long number) {
			this.sb.append(sep);
			this.sb.append(number);
		}
		
		public final void append(final char open, final String s, final char close) {
			this.sb.append(open);
			this.sb.append(s);
			this.sb.append(close);
		}
		
		public final void append(final char open, final int number, final char close) {
			this.sb.append(open);
			this.sb.append(number);
			this.sb.append(close);
		}
		
		public final void append(final char open, final long number, final char close) {
			this.sb.append(open);
			this.sb.append(number);
			this.sb.append(close);
		}
		
		public final void appendFormat(final String valueFormat, final @Nullable Object... valueArgs) {
			Formatter formatter= this.formatter;
			if (formatter == null) {
				formatter= new Formatter(this.sb, Locale.ENGLISH);
				this.formatter= formatter;
			}
			formatter.format(valueFormat, valueArgs);
		}
		
		public final void appendLines(final String lines) {
			appendLines(lines, LINE_PREFIX + CONT_INDENT);
		}
		
		public final void appendLines(final char sep, final String lines) {
			this.sb.append(sep);
			appendLines(lines, LINE_PREFIX + CONT_INDENT);
		}
		
		public final void appendLines(final List<@NonNull String> lines) {
			final int n= lines.size();
			if (n == 0) {
				return;
			}
			append(lines.get(0));
			for (int i= 1; i < n; i++) {
				append(LINE_PREFIX + CONT_INDENT);
				lines.get(i);
			}
		}
		
		private void appendLines(final String s, final String contPrefix) {
			int start= 0;
			int end= s.indexOf('\n', start);
			
			if (end < 0) {
				append(s);
				return;
			}
			
			if (end > 0 && s.charAt(end - 1) == '\r') {
				append(s, start, end - 1);
			}
			else {
				append(s, start, end);
			}
			start= end + 1;
			while ((end= s.indexOf('\n', start)) >= 0) {
				append(contPrefix);
				if (end > 0 && s.charAt(end - 1) == '\r') {
					append(s, start, end - 1);
				}
				else {
					append(s, start, end);
				}
				start= end + 1;
			}
			if (start < s.length()) {
				append(contPrefix);
				append(s, start, s.length());
			}
		}
		
		
		public void addProp(final String name) {
			this.sb.append(PROP_PREFIX);
			this.sb.append(name);
			this.sb.append(PROP_ASSIGN);
		}
		
		public void addProp(final String name, final @Nullable String value) {
			addProp(name);
			
			if (value == null) {
				this.sb.append(NULL);
				return;
			}
			appendLines(value, PROP_PREFIX + CONT_INDENT);
		}
		
		
		public void addProp(final String name, final boolean value) {
			addProp(name);
			
			this.sb.append(value);
		}
		
		public void addProp(final String name, final int value) {
			addProp(name);
			
			this.sb.append(value);
		}
		
		public void addProp(final String name, final long value) {
			addProp(name);
			
			this.sb.append(value);
		}
		
		public void addProp(final String name, final float value) {
			addProp(name);
			
			this.sb.append(value);
		}
		
		public void addProp(final String name, final double value) {
			addProp(name);
			
			this.sb.append(value);
		}
		
		
		public void addProp(final String name, final @Nullable Object value) {
			addProp(name);
			
			if (value == null) {
				this.sb.append(NULL);
				return;
			}
			appendLines(value.toString(), PROP_PREFIX + CONT_INDENT);
		}
		
		public void addProp(final String name, final @Nullable Collection<?> value) {
			addProp(name);
			
			if (value == null) {
				this.sb.append(NULL);
				return;
			}
			if (value instanceof List) {
				this.sb.append('[');
			}
			else {
				this.sb.append('{');
			}
			if (!value.isEmpty()) {
				for (final Object e : value) {
					this.sb.append(PROP_PREFIX + INDENT);
					if (e == null) {
						this.sb.append(NULL);
						continue;
					}
					appendLines(e.toString(), PROP_PREFIX + INDENT + CONT_INDENT); 
				}
				this.sb.append(PROP_PREFIX);
			}
			if (value instanceof List) {
				this.sb.append(']');
			}
			else {
				this.sb.append('}');
			}
		}
		
		public void addProp(final String name, final String valueFormat, final @Nullable Object... valueArgs) {
			addProp(name);
			
			appendFormat(valueFormat, valueArgs);
		}
		
		public String build() {
			return this.sb.toString();
		}
		
		@Override
		public String toString() {
			return this.sb.toString();
		}
		
	}
	
	
	public static final Class<@NonNull Object> NonNull_Object_TYPE= Object.class;
	@SuppressWarnings("null")
	public static final Class<@Nullable Object> Nullable_Object_TYPE= Object.class;
	
	public static final Class<@NonNull Object[]> NonNull_ObjectArray_TYPE= Object[].class;
	@SuppressWarnings("null")
	public static final Class<@Nullable Object[]> Nullable_ObjectArray_TYPE= Object[].class;
	
	public static final Class<@NonNull String> NonNull_String_TYPE= String.class;
	@SuppressWarnings("null")
	public static final Class<@Nullable String> Nullable_String_TYPE= String.class;
	
	public static final Class<@NonNull String[]> NonNull_StringArray_TYPE= String[].class;
	@SuppressWarnings("null")
	public static final Class<@Nullable String[]> Nullable_StringArray_TYPE= String[].class;
	
	
	public static boolean isNull(final @Nullable Object object) {
		return (object == null);
	}
	
	public static boolean isAnyNull(final @Nullable Object object1, final @Nullable Object object2) {
		return (object1 == null || object2 == null);
	}
	
	@SafeVarargs
	public static <T> boolean isAnyNull(final T... objects) {
		for (int i= 0; i < objects.length; i++) {
			if (objects[i] == null) {
				return true;
			}
		}
		return false;
	}
	
	
	public static <T> @NonNull T nonNullAssert(final @Nullable T object) {
		if (object == null) {
			throw new NullPointerException();
		}
		return object;
	}
	
	public static <T> @NonNull T nonNullElse(final @Nullable T object, final @NonNull T elseObj) {
		return (object != null) ? object : elseObj;
	}
	
	public static <T> @NonNull T nonNullElse(final @Nullable T object,
			final Supplier<? extends @NonNull T> elseSupplier) {
		return (object != null) ? object : elseSupplier.get();
	}
	
	/**
	 * Marks a @NonNull field as late initialized.
	 * 
	 * @param <T> the type
	 * @return <code>null</code>
	 */
	@SuppressWarnings("null")
	public static <T> @NonNull T nonNullLateInit() {
		return null;
	}
	
	public static <T> @Nullable T nullable(final @Nullable T object) {
		return object;
	}
	
	
	private ObjectUtils() {}
	
}
