/*******************************************************************************
 * Copyright (c) 2013 Christian Pontesegger and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Christian Pontesegger - initial API and implementation
 *******************************************************************************/
package org.eclipse.ease.debugging.model;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IValue;

public class EaseDebugValue implements IValue {

	public static boolean isPrimitiveType(final Object value) {
		return (value instanceof Integer) || (value instanceof Byte) || (value instanceof Short) || (value instanceof Boolean) || (value instanceof Character)
				|| (value instanceof Long) || (value instanceof Double) || (value instanceof Float);
	}

	private static Collection<Field> getFields(Class<? extends Object> clazz) {
		final Collection<Field> fields = new HashSet<>();
		fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
		fields.addAll(Arrays.asList(clazz.getFields()));

		final Class<?> superclass = clazz.getSuperclass();
		if (superclass != null)
			fields.addAll(getFields(superclass));

		return fields;
	}

	private IDebugElement fParent;

	private Object fValue;

	private List<EaseDebugVariable> fVariables = null;

	private String fValueString = null;

	public EaseDebugValue(final IDebugElement parent, final Object value) {
		fParent = parent;
		fValue = value;
	}

	public void setParent(IDebugElement parent) {
		fParent = parent;

		// do not use getVariables() here as we do not want to deeply populate everything right now.
		if (fVariables != null) {
			for (final EaseDebugVariable variable : fVariables)
				variable.setParent(fParent);
		}
	}

	@Override
	public String getReferenceTypeName() {
		if (getValue() != null) {
			if (isPrimitiveType(getValue())) {
				if (getValue() instanceof Integer)
					return "int";
				if (getValue() instanceof Boolean)
					return "bool";
				if (getValue() instanceof Character)
					return "char";

				return fValue.getClass().getSimpleName().toLowerCase();
			}

			return getValue().getClass().getSimpleName();
		}

		return "";
	}

	@Override
	public String getValueString() {
		if (fValueString != null)
			return fValueString;

		if (isPrimitiveType(fValue))
			return fValue.toString();

		if (fValue instanceof String)
			return "\"" + fValue + "\" (id=" + getUniqueID(getValue()) + ")";

		if (getValue() != null) {
			if (getValue().getClass().isArray())
				return fValue.getClass().getComponentType().getSimpleName() + "[" + Array.getLength(getValue()) + "] (id=" + getUniqueID(getValue()) + ")";

			return fValue.getClass().getSimpleName() + " (id=" + getUniqueID(getValue()) + ")";

		} else
			return "null";
	}

	private String getUniqueID(Object value) {
		if (getDebugTarget() != null)
			return Integer.toString(getDebugTarget().getUniqueVariableId(value));

		return "<none>";
	}

	@Override
	public boolean isAllocated() {
		return fValue != null;
	}

	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (String.class.equals(adapter))
			return (T) ((fValue != null) ? fValue.toString() : "");

		return null;
	}

	@Override
	public EaseDebugTarget getDebugTarget() {
		// FIXME can we change fParent to EaseDebugElement?
		if (fParent != null)
			return (EaseDebugTarget) fParent.getDebugTarget();

		return null;
	}

	@Override
	public String getModelIdentifier() {
		return getDebugTarget().getModelIdentifier();
	}

	@Override
	public ILaunch getLaunch() {
		return getDebugTarget().getLaunch();
	}

	public Object getValue() {
		return fValue;
	}

	@Override
	public EaseDebugVariable[] getVariables() {
		if (fVariables == null) {
			fVariables = new ArrayList<>();

			if (getValue() == null)
				return new EaseDebugVariable[0];

			if (isPrimitiveType(getValue()))
				return new EaseDebugVariable[0];

			if (getValue().getClass().isArray()) {
				final int length = Array.getLength(getValue());
				for (int index = 0; index < length; index++) {
					final EaseDebugVariable variable = new EaseJavaArrayElementVariable(index, getValue(), fParent);
					fVariables.add(variable);
				}

			} else if (getValue() instanceof Collection<?>) {
				final Collection<?> asCollection = (Collection<?>) getValue();
				int index = 0;
				for (final Object value : asCollection) {
					final EaseDebugVariable variable = new EaseDebugVariable(String.format("[%d]", index++), value, fParent, null);
					fVariables.add(variable);
				}
			} else {

				// populate generic Java fields
				Collection<Field> fields = getFields(getValue().getClass());
				fields = fields.stream().filter(field -> !Modifier.isStatic(field.getModifiers())).collect(Collectors.toSet());

				for (final Field field : fields) {
					try {
						field.setAccessible(true);
						final EaseDebugVariable variable = new EaseJavaFieldVariable(field, getValue(), fParent);
						fVariables.add(variable);
					} catch (final IllegalArgumentException e) {
						// ignore
					} catch (final IllegalAccessException e) {
						// ignore
					}
				}
			}

			sortVariables();
		}

		return fVariables.toArray(new EaseDebugVariable[fVariables.size()]);
	}

	@Override
	public boolean hasVariables() {
		if (getValue() == null)
			return false;

		if (isPrimitiveType(getValue()))
			return false;

		// in case we did not fetch variables yet we delay evaluation and pretend we have children
		return (fVariables != null) ? (getVariables().length > 0) : true;
	}

	public void setVariables(Collection<EaseDebugVariable> variables) {
		if (variables != null) {
			fVariables = new ArrayList<>(variables);
			sortVariables();
		}
	}

	public void update(Object value) {
		fValue = value;
		fVariables = null;
	}

	public void setValueString(String valueString) {
		fValueString = valueString;
	}

	private void sortVariables() {

		Collections.sort(fVariables, (o1, o2) -> {
			final String name1 = o1.getName();
			final String name2 = o2.getName();

			if ((name1.startsWith("[")) && (name1.endsWith("]")) && (name2.startsWith("[")) && (name2.endsWith("]"))) {
				// array operator
				try {
					final int index1 = Integer.parseInt(name1.substring(1, name1.length() - 1));
					final int index2 = Integer.parseInt(name2.substring(1, name2.length() - 1));

					return index1 - index2;
				} catch (final NumberFormatException e) {
					// not a number, ignore and use string compare
				}
			}

			return name1.compareTo(name2);
		});
	}
}
