package com.capgemini.framework.teamcenter.queries.saved.modelobject;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.queries.saved.AbstractReplicatedQuery;
import com.teamcenter.soa.client.model.ModelObject;
import com.teamcenter.soa.client.model.strong.Item;
import com.teamcenter.soa.client.model.strong.ItemRevision;

/**
 * Looks for a ModelObject in Teamcenter.
 *
 * @param <QUERY> the type of the actual daughter class. Provided to chain requests.
 * @param <OBJ> the expected type of the Object: either {@link Item} or {@link ItemRevision}
 */
public abstract class AbstractModelObjectQuery<OBJ extends ModelObject, QUERY extends AbstractModelObjectQuery<OBJ, QUERY>>
        extends AbstractReplicatedQuery<OBJ, QUERY> {
    private static final String PARAM_OBJECT_TYPE = "Type";
    private static final String VALUE_OBJECT_TYPE_PRODUCT = "Product";
    private static final String VALUE_OBJECT_TYPE_GENERIC = "Generic";
    private static final String VALUE_OBJECT_TYPE_GENERIC_ASSEMB = "Generic Assemb";

    protected AbstractModelObjectQuery(final TcSession session, final String queryNameSuffix) {
        super(session, queryNameSuffix);
    }

    /**
     * Demande a cette requete de rechercher un objet d'un certain type.
     *
     * @param requestedType the constraint on object type
     * @return Cette meme requete, pour chainer les parametres.
     */
    public QUERY searchType(final String requestedType) {
        return this.addParam(PARAM_OBJECT_TYPE, requestedType);
    }

    /**
     * Demande a cette requete de rechercher un Generic.
     *
     * @return Cette meme requete, pour chainer les parametres.
     */
    public QUERY searchGeneric() {
        return this.addParam(PARAM_OBJECT_TYPE, VALUE_OBJECT_TYPE_GENERIC);
    }

    /**
     * Demande a cette requete de rechercher un Generic Assemb.
     *
     * @return Cette meme requete, pour chainer les parametres.
     */
    public QUERY searchGenericAssemb() {
        return this.addParam(PARAM_OBJECT_TYPE, VALUE_OBJECT_TYPE_GENERIC_ASSEMB);
    }

    /**
     * Demande a cette requete de rechercher un Product.
     *
     * @return Cette meme requete, pour chainer les parametres.
     */
    public QUERY searchProduct() {
        return this.addParam(PARAM_OBJECT_TYPE, VALUE_OBJECT_TYPE_PRODUCT);
    }

    /**
     * Demande a cette requete de rechercher le nom d'objet fourni..
     *
     * @param itemName Le nom a rechercher. (exemple: "M88 MOTEUR ASSEMBLE")
     * @return Cette meme requete, pour chainer les parametres.
     */
    @Override
    public QUERY searchName(final String itemName) {
        return this.addParam(PARAM_OBJECT_NAME, itemName);
    }

    @Override
    public QUERY addParam(final String aParamName, final String aParamValue) {
        super.parameters.put(aParamName, aParamValue);
        return selfCast();
    }

}
