/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.ode.daohib.bpel;

import org.apache.ode.daohib.SessionManager;
import org.apache.ode.daohib.bpel.hobj.HObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.Query;
import org.hibernate.Session;

import java.io.Serializable;
import java.util.List;

/**
 * Base class for our DAO objects.
 * <p>
 * All subclass methods that might trigger SQL queries should log a message in the log category 'org.apache.ode.bpel.DAO' when entered.
 * A typical message could be "className.methodName". <br/>
 * Typical candidates are setters, finders and getters of entities. Getters of simple properties won't provide relevant information.
 */
public abstract class HibernateDao {

    // logger used by subclasses to track entered methods that may trigger sql query
    // we don't use the package name to avoid interferences with other logging info.
    static final Logger logDao = LoggerFactory.getLogger("org.apache.ode.bpel.DAO");

    protected final SessionManager _sm;
    protected final HObject _hobj;

    protected HibernateDao(SessionManager sessionManager, HObject hobj) {
        _sm = sessionManager;
        _hobj = hobj;
    }

    void entering(String msg){
        // add a prefix to be parser friendly
        if(logDao.isDebugEnabled()) logDao.debug("entering "+msg);
    }

    void leaving(String msg){
        if(logDao.isDebugEnabled()) logDao.debug("leaving "+msg);
    }

    /**
     * @see org.apache.ode.utils.dao.DAO#getDHandle()
     */
    public Serializable getDHandle() {
        return new HibernateHandle(getClass(), _hobj.getClass(), getSession().getIdentifier(_hobj));
    }

    protected Session getSession() {
        return _sm.getSession();
    }

    public HObject getHibernateObj() {
        return _hobj;
    }

    public Serializable getId() {
        if( _hobj != null ) {
            return _hobj.getId();
        }
        return null;
    }

    public boolean equals(Object obj) {
        assert obj instanceof HibernateDao;
        return _hobj.getId().equals(((HibernateDao) obj)._hobj.getId());
    }

    public int hashCode() {
        return _hobj.getId().hashCode();
    }

    protected void update() {
        _sm.getSession().update(_hobj);
    }

    @SuppressWarnings("unchecked")
    protected void deleteByIds(Class entity, List<Long> ids) {
        deleteByColumn(entity, "id", ids);
    }

    @SuppressWarnings("unchecked")
    protected void deleteByColumn(Class entity, String column, List<Long> values) {
        if( values != null && values.size() > 0 ) {
            final String delete = "delete from "+entity.getName()+" as e where e."+column+" in (:values)";

            // some databases don't like long lists of values with IN operator
            // so we delete in batches.  Oracle 9i, for instance, doesn't support
            // more than 1000 -- we opt to be conservative.
            final int batchSize = 100;

            int index = 0;
            while (index < values.size()) {
                List<Long> subList = values.subList(index, Math.min(index+batchSize, values.size()));
                Query query = getSession().createQuery(delete);
                query.setParameterList("values", subList);
                query.executeUpdate();
                index += batchSize;
            }
        }
    }
}
