/**
 * Copyright (c) 2014, 2018 itemis AG (http://www.itemis.eu) 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
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package org.eclipse.xtext.xbase.lib.util;

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.util.ToStringContext;

/**
 * Helps with the construction of good {@link Object#toString()} representations.
 * <p>You can customize the output using the builder-style methods {@link ToStringBuilder#singleLine()} {@link ToStringBuilder#skipNulls()} and {@link ToStringBuilder#hideFieldNames()}.</p>
 * <p>You can either directly list fields to include via {@link ToStringBuilder#add(String, Object)} and {@link ToStringBuilder#add(Object)}
 * or you can let the builder do it automatically using reflection, either including the fields declared in this class or including all superclasses.</p>
 * <p>The builder will automatically handle cycles in the object tree. It also pretty prints arrays and Iterables.</p>
 *
 * This class is not thread safe.
 * @since 2.7
 */
@Beta
@GwtCompatible
@SuppressWarnings("all")
public final class ToStringBuilder {
	
	private static ToStringContext toStringContext = ToStringContext.INSTANCE;
	
	private final Object instance;

	private final String typeName;

	private boolean multiLine = true;

	private boolean skipNulls = false;

	private boolean showFieldNames = true;

	private boolean prettyPrint = true;

	private final List<Part> parts = new ArrayList<Part>();

	/**
	 * Creates a new ToStringBuilder for the given object. If you don't use reflection, then this instance
	 * is only used for obtaining its classes' simple name.
	 *
	 * @param instance the object to convert to a String
	 */
	public ToStringBuilder(final Object instance) {
		this.instance = instance;
		this.typeName = instance.getClass().getSimpleName();
	}

	/**
	 * Fields are printed on a single line, separated by commas instead of newlines
	 * @return this
	 */
	public ToStringBuilder singleLine() {
		this.multiLine = false;
		return this;
	}

	/**
	 * Fields with null values will be excluded from the output
	 * @return this
	 */
	public ToStringBuilder skipNulls() {
		this.skipNulls = true;
		return this;
	}

	/**
	 * Field names will not be included in the output. Useful for small classes.
	 * @return this
	 */
	public ToStringBuilder hideFieldNames() {
		this.showFieldNames = false;
		return this;
	}

	/**
	 * By default, Iterables, Arrays and multiline Strings are pretty-printed.
	 * Switching to their normal representation makes the toString method significantly faster.
	 * @since 2.9
	 * @return this
	 */
	public ToStringBuilder verbatimValues() {
		this.prettyPrint = false;
		return this;
	}

	/**
	 * Adds all fields declared directly in the object's class to the output
	 * @return this
	 */
	@GwtIncompatible("Class.getDeclaredFields")
	public ToStringBuilder addDeclaredFields() {
		Field[] fields = instance.getClass().getDeclaredFields();
		for(Field field : fields) {
			addField(field);
		}
		return this;
	}

	/**
	 * Adds all fields declared in the object's class and its superclasses to the output.
	 * @return this
	 */
	@GwtIncompatible("Class.getDeclaredFields")
	public ToStringBuilder addAllFields() {
		List<Field> fields = getAllDeclaredFields(instance.getClass());
		for(Field field : fields) {
			addField(field);
		}
		return this;
	}

	/**
	 * @param fieldName the name of the field to add to the output using reflection
	 * @return this
	 */
	@GwtIncompatible("Class.getDeclaredField(String)")
	public ToStringBuilder addField(final String fieldName) {
		List<Field> fields = getAllDeclaredFields(instance.getClass());
		for(Field field : fields) {
			if(fieldName.equals(field.getName())) {
				addField(field);
				break;
			}
		}
		return this;
	}

	@GwtIncompatible("java.lang.reflect.Field")
	private ToStringBuilder addField(final Field field) {
		if (!Modifier.isStatic(field.getModifiers())) {
			field.setAccessible(true);
			try {
				add(field.getName(), field.get(instance));
			} catch(IllegalAccessException e) {
				throw Exceptions.sneakyThrow(e);
			}
		}
		return this;
	}

	/**
	 * @param value the value to add to the output
	 * @param fieldName the field name to list the value under
	 * @return this
	 */
	public ToStringBuilder add(final String fieldName, final Object value) {
		return addPart(fieldName, value);
	}

	/**
	 * @param value the value to add to the output without a field name
	 * @return this
	 */
	public ToStringBuilder add(final Object value) {
		return addPart(value);
	}

	private Part addPart() {
		final Part p = new Part();
		this.parts.add(p);
		return p;
	}

	private ToStringBuilder addPart(final Object value) {
		final Part p = this.addPart();
		p.value = value;
		return this;
	}

	private ToStringBuilder addPart(final String fieldName, final Object value) {
		final Part p = this.addPart();
		p.fieldName = fieldName;
		p.value = value;
		return this;
	}

	/**
	 * @return the String representation of the processed object
	 */
	@Override
	public String toString() {
		boolean startProcessing = ToStringBuilder.toStringContext.startProcessing(this.instance);
		if (!startProcessing) {
			return this.toSimpleReferenceString(this.instance);
		}
		try {
			final IndentationAwareStringBuilder builder = new IndentationAwareStringBuilder();
			builder.append(typeName).append(" ");
			builder.append("[");
			String nextSeparator = "";
			if (multiLine) {
				builder.increaseIndent();
			}
			for (Part part : parts) {
				if (!skipNulls || part.value != null) {
					if (multiLine) {
						builder.newLine();
					} else {
						builder.append(nextSeparator);
						nextSeparator = ", ";
					}
					if (part.fieldName != null && this.showFieldNames) {
						builder.append(part.fieldName).append(" = ");
					}
					this.internalToString(part.value, builder);
				}
			}
			if (multiLine) {
				builder.decreaseIndent().newLine();
			}
			builder.append("]");
			return builder.toString();
		} finally {
			ToStringBuilder.toStringContext.endProcessing(this.instance);
		}
	}

	private void internalToString(final Object object, final IndentationAwareStringBuilder sb) {
		if (prettyPrint) {
			if (object instanceof Iterable<?>) {
				serializeIterable((Iterable<?>)object, sb);
			} else if (object instanceof Object[]) {
				sb.append(Arrays.toString((Object[])object));
			} else if (object instanceof byte[]) {
				sb.append(Arrays.toString((byte[])object));
			} else if (object instanceof char[]) {
				sb.append(Arrays.toString((char[])object));
			} else if (object instanceof int[]) {
				sb.append(Arrays.toString((int[])object));
			} else if (object instanceof boolean[]) {
				sb.append(Arrays.toString((boolean[])object));
			} else if (object instanceof long[]) {
				sb.append(Arrays.toString((long[])object));
			} else if (object instanceof float[]) {
				sb.append(Arrays.toString((float[])object));
			} else if (object instanceof double[]) {
				sb.append(Arrays.toString((double[])object));
			} else if (object instanceof CharSequence) {
				sb.append("\"").append(((CharSequence)object).toString().replace("\n", "\\n").replace("\r", "\\r")).append("\"");
			} else if (object instanceof Enum<?>) {
				sb.append(((Enum<?>)object).name());
			} else {
				sb.append(String.valueOf(object));
			}
		} else {
			sb.append(String.valueOf(object));
		}
	}

	private void serializeIterable(final Iterable<?> object, final IndentationAwareStringBuilder sb) {
		final Iterator<?> iterator = object.iterator();
		sb.append(object.getClass().getSimpleName()).append(" (");
		if (multiLine) {
			sb.increaseIndent();
		}
		boolean wasEmpty = true;
		while (iterator.hasNext()) {
			wasEmpty = false;
			if (multiLine) {
				sb.newLine();
			}
			this.internalToString(iterator.next(), sb);
			if (iterator.hasNext()) {
				sb.append(",");
			}
		}
		if (multiLine) {
			sb.decreaseIndent();
		}
		if (!wasEmpty && this.multiLine) {
			sb.newLine();
		}
		sb.append(")");
	}

	private String toSimpleReferenceString(final Object obj) {
		String simpleName = obj.getClass().getSimpleName();
		int identityHashCode = System.identityHashCode(obj);
		return simpleName + "@" + Integer.valueOf(identityHashCode);
	}

	@GwtIncompatible("java.lang.reflect.Field")
	private List<Field> getAllDeclaredFields(final Class<?> clazz) {
		final ArrayList<Field> result = new ArrayList();

		for(Class<?> current = clazz; current != null; current = current.getSuperclass()) {
			Field[] declaredFields = current.getDeclaredFields();
			result.addAll(Arrays.asList(declaredFields));
			
		}
		return result;
	}

	private static final class Part {
		private String fieldName;
		private Object value;
	}

	private static class IndentationAwareStringBuilder {
		private final StringBuilder builder = new StringBuilder();

		private final String indentationString = "  ";

		private final String newLineString = "\n";

		private int indentation = 0;

		public IndentationAwareStringBuilder increaseIndent() {
			indentation++;
			return this;
		}

		public IndentationAwareStringBuilder decreaseIndent() {
			indentation--;
			return this;
		}

		public IndentationAwareStringBuilder append(final CharSequence string) {
			if (indentation > 0) {
				String indented = string.toString().replace(
					newLineString,
					newLineString + Strings.repeat(indentationString, indentation)
				);
				builder.append(indented);
			} else {
				builder.append(string);
			}
			return this;
		}

		public IndentationAwareStringBuilder newLine() {
			builder.append(newLineString).
			append(Strings.repeat(this.indentationString, this.indentation));
			return this;
		}

		@Override
		public String toString() {
			return this.builder.toString();
		}
	}
}
