package eu.dnetlib.functionality.index.model.impl;

import java.io.Serializable;

import eu.dnetlib.functionality.index.model.*;

import static java.lang.String.format;

/**
 * Basic abstract implementation class for Any.
 */
public abstract class AbstractAny implements Any, Serializable {

	/** because it is serializable. */
	private static final long serialVersionUID = 1L;

	/**
	 * type of this value object.
	 */
	protected final ValueType _valueType;

	/**
	 * Constructs a new AbstractAny.
	 * 
	 * @param valueType
	 *            the type of the AnbstractAny.
	 */
	protected AbstractAny(final ValueType valueType) {
		_valueType = valueType;
	}

	/** {@inheritDoc} */
	@Override
	public ValueType getValueType() {
		return _valueType;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isMap() {
		return _valueType == ValueType.MAP;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isSeq() {
		return _valueType == ValueType.SEQ;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isValue() {
		// return _valueType == ValueType.STRING || _valueType == ValueType.DOUBLE || _valueType == ValueType.BOOLEAN
		// || _valueType == ValueType.LONG || _valueType == ValueType.DATE || _valueType == ValueType.DATETIME;
		return _valueType != ValueType.MAP && _valueType != ValueType.SEQ;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isString() {
		return _valueType == ValueType.STRING;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isDouble() {
		return _valueType == ValueType.DOUBLE;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isBoolean() {
		return _valueType == ValueType.BOOLEAN;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isLong() {
		return _valueType == ValueType.LONG;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isDate() {
		return _valueType == ValueType.DATE;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isDateTime() {
		return _valueType == ValueType.DATETIME;
	}

	/** {@inheritDoc} */
	@Override
	public boolean isNumber() {
		return _valueType == ValueType.LONG || _valueType == ValueType.DOUBLE;
	}

	/** {@inheritDoc} */
	@Override
	public DataFactory getFactory() {
		return DefaultDataFactoryImpl.INSTANCE;
	}

	@Override
	public Value asValue() {
		throw new InvalidValueTypeException(format("cannot return a %s as a Value", _valueType));
	}

	@Override
	public AnyMap asMap() {
		throw new InvalidValueTypeException(format("cannot return a %s as a %s", _valueType, ValueType.MAP));
	}

	@Override
	public AnySeq asSeq() {
		throw new InvalidValueTypeException(format("cannot return a %s as a %s", _valueType, ValueType.SEQ));
	}

}
