package org.eclipse.osbp.jpa.services.history;

import java.lang.reflect.Field;
import java.util.List;

import javax.persistence.Version;

import org.eclipse.osbp.runtime.common.annotations.HistIsCurrent;
import org.eclipse.osbp.runtime.common.annotations.HistIsCustomVersion;
import org.eclipse.osbp.runtime.common.annotations.HistValidUntil;
import org.eclipse.osbp.runtime.common.historized.UUIDHist;
import org.eclipse.osbp.runtime.common.util.BeanUtils;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.DatabaseMapping;

public class HistorizedDescriptorWrapper {

	private final Class<?> clazz;
	private final ClassDescriptor descriptor;
	private DatabaseMapping versionMapping;
	private DatabaseMapping validUntilMapping;
	private DatabaseMapping currentMapping;
	private DatabaseMapping isCustomVersionMapping;

	private DatabaseMapping idMapping;
	private ClassDescriptor uuidHistDescriptor;
	private DatabaseMapping id_idMapping;
	private DatabaseMapping id_validFromMapping;

	public HistorizedDescriptorWrapper(ClassDescriptor descriptor) {
		this.clazz = descriptor.getJavaClass();
		this.descriptor = descriptor;

		// find the ID String field by the descriptor
		List<DatabaseField> pk = descriptor.getPrimaryKeyFields();
		for (DatabaseMapping mapping : descriptor.getMappings()) {
			if (mapping.isPrimaryKeyMapping()) {
				idMapping = mapping;
				break;
			}
		}

		uuidHistDescriptor = idMapping.getReferenceDescriptor();

		Field versionField = BeanUtils.getField(clazz, Version.class);
		Field validUntilField = BeanUtils.getField(clazz, HistValidUntil.class);
		Field currentHist = BeanUtils.getField(clazz, HistIsCurrent.class);
		Field isCustomVersion = BeanUtils.getField(clazz, HistIsCustomVersion.class);

		id_idMapping = uuidHistDescriptor.getMappingForAttributeName("id");
		id_validFromMapping = uuidHistDescriptor.getMappingForAttributeName("validFrom");
		versionMapping = descriptor.getMappingForAttributeName(versionField.getName());
		validUntilMapping = descriptor.getMappingForAttributeName(validUntilField.getName());
		currentMapping = descriptor.getMappingForAttributeName(currentHist.getName());
		isCustomVersionMapping = descriptor.getMappingForAttributeName(isCustomVersion.getName());
	}

	public String getIdAttName() {
		return idMapping.getAttributeName();
	}

	public String getId_IdAttName() {
		return id_idMapping.getAttributeName();
	}

	public String getId_ValidFromAttName() {
		return id_validFromMapping.getAttributeName();
	}

	public String getVersionAttName() {
		return versionMapping.getAttributeName();
	}

	public String getValidUntilAttName() {
		return validUntilMapping.getAttributeName();
	}

	public String getCurrentHistAttName() {
		return currentMapping.getAttributeName();
	}

	public String getIsCustomVersionAttName() {
		return isCustomVersionMapping.getAttributeName();
	}

	public UUIDHist getID(Object obj) {
		return (UUIDHist) idMapping.getAttributeValueFromObject(obj);
	}

	public int getVersion(Object obj) {
		return (int) versionMapping.getAttributeValueFromObject(obj);
	}

	public long getId_ValidFrom(Object obj) {
		if (obj instanceof UUIDHist) {
			return ((UUIDHist) obj).getValidFrom();
		}
		UUIDHist idHist = (UUIDHist) idMapping.getAttributeValueFromObject(obj);
		return idHist != null ? idHist.getValidFrom() : -1;
	}

	public String getId_IdFrom(Object obj) {
		if (obj instanceof UUIDHist) {
			return ((UUIDHist) obj).getId();
		}
		UUIDHist idHist = (UUIDHist) idMapping.getAttributeValueFromObject(obj);
		return idHist != null ? idHist.getId() : null;
	}

	public long getValidUntil(Object obj) {
		return (long) validUntilMapping.getAttributeValueFromObject(obj);
	}

	public boolean isCurrentHist(Object obj) {
		return (boolean) currentMapping.getAttributeValueFromObject(obj);
	}

	public boolean isCustomVersion(Object obj) {
		return (boolean) isCustomVersionMapping.getAttributeValueFromObject(obj);
	}

	public Class<?> getEntityClass() {
		return descriptor.getJavaClass();
	}

	public void setID(Object obj, Object value) {
		idMapping.setAttributeValueInObject(obj, value);
	}

	public void setVersion(Object obj, int value) {
		versionMapping.setAttributeValueInObject(obj, value);
	}

	public void setId_ValidFrom(Object obj, long value) {
		if (obj instanceof UUIDHist) {
			((UUIDHist) obj).setValidFrom(value);
		}
		UUIDHist idHist = (UUIDHist) idMapping.getAttributeValueFromObject(obj);
		if (idHist != null) {
			idHist.setValidFrom(value);
		}
	}

	public void setId_IdFrom(Object obj, String value) {
		if (obj instanceof UUIDHist) {
			((UUIDHist) obj).setId(value);
		}
		UUIDHist idHist = (UUIDHist) idMapping.getAttributeValueFromObject(obj);
		if (idHist != null) {
			idHist.setId(value);
		}
	}

	public void setValidUntil(Object obj, long value) {
		validUntilMapping.setAttributeValueInObject(obj, value);
	}

	public void setCurrentHist(Object obj, boolean value) {
		currentMapping.setAttributeValueInObject(obj, value);
	}

	public void setCustomVersion(Object obj, boolean value) {
		isCustomVersionMapping.setAttributeValueInObject(obj, value);
	}

}
