package eu.dnetlib.dlms.jdbc;

import java.sql.SQLException;

import eu.dnetlib.dlms.jdbc.server.Variable;
import eu.dnetlib.dlms.lowlevel.objects.LLDigitalObject;

/**
 * InformationObjects are the objects returned in a ResultSet instead of LLDigitalObject.
 * 
 * @author alessia
 * 
 */
public class InformationObjectImpl implements InformationObject {
	/** Identifier. */
	private long id;
	/** Type of the object that has id as identifier. */
	private String type;
	/**
	 * The set name of the object. Objects may belong to several set, this set is the set from which the object has been
	 * selected.
	 */
	private String set;

	/**
	 * Parses a long from an object descriptor string. String should match "id,type".
	 * 
	 * @param descriptor
	 *            string to parse
	 * @return a long
	 */
	static protected long parseId(final String descriptor) {
		return Long.parseLong(descriptor.split(",")[0]);
	}

	/**
	 * Parses the string representing an object type from the descriptor string. Format of the string to parse is
	 * "is,type".
	 * 
	 * @param descriptor
	 *            string to parse
	 * @return a string
	 */
	static protected String parseType(final String descriptor) {
		if (descriptor.contains(","))
			return descriptor.split(",")[1];
		return "unknown";
	}

	static protected String parseSet(final String descriptor) {
		if (descriptor.contains(",")) {
			final String[] splitted = descriptor.split(",");
			if (splitted.length >= 3)
				return splitted[2];
		}
		return "unknown";
	}

	/** Constructor. */
	public InformationObjectImpl() {
		//left blank
	}

	/**
	 * Constructor.
	 * 
	 * @param descriptor
	 *            String that describes the object, holding its identifier and type.
	 */
	public InformationObjectImpl(final String descriptor) {
		this.id = parseId(descriptor);
		this.type = parseType(descriptor);
		this.set = parseSet(descriptor);
	}

	/**
	 * Constructor. Creates an InformationObjectImpl with the given id and unknown type.
	 * 
	 * @param id
	 *            long identifier
	 */
	public InformationObjectImpl(final long id) {
		this.id = id;
		this.type = "unknown";
		this.set = "unknown";
	}

	/**
	 * Constructor. Creates an InformationObjectImpl with the same id as obj and sets the type to the name of obj's
	 * objectType.
	 * 
	 * @param obj
	 *            LLDigitalObject this instance will represents
	 */
	@Deprecated
	public InformationObjectImpl(final LLDigitalObject obj) {
		this(obj, "unknown");
	}

	public InformationObjectImpl(final LLDigitalObject obj, final String srcSet) {
		this.id = obj.getId();
		this.type = obj.getObjectType().getName();
		this.set = srcSet;
	}

	public InformationObjectImpl(final Variable<?> v, final String srcSet) throws SQLException {
		switch (v.getVariableType()) {
		case atom:
		case object:
		case relation:
		case set:
		case structure:
			final LLDigitalObject obj = (LLDigitalObject) v.getVariableValue();
			this.id = obj.getId();
			this.type = obj.getObjectType().getName();
			this.set = srcSet;
			break;
		default:
			throw new SQLException("Cannot create " + this.getClass() + " from variable of type: " + v.getVariableType());
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InformationObjectImpl [id=" + this.id + ", set=" + this.set + ", type=" + this.type + "]";
	}

	public void setId(final long id) {
		this.id = id;
	}

	public long getId() {
		return this.id;
	}

	public String getType() {
		return this.type;
	}

	public void setType(final String type) {
		this.type = type;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.dlms.jdbc.InformationObject#getSet()
	 */
	@Override
	public String getSet() {
		return this.set;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.dlms.jdbc.InformationObject#setSet(java.lang.String)
	 */
	@Override
	public void setSet(final String setName) {
		this.set = setName;
	}

}
