package jp.sourceforge.shovel.dao.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jp.sourceforge.shovel.dao.IUserCustomDao;
import jp.sourceforge.shovel.entity.IUser;
import jp.sourceforge.shovel.util.ShovelUtil;

import org.apache.commons.lang.ArrayUtils;
import org.seasar.dao.DaoMetaDataFactory;
import org.seasar.dao.impl.AbstractDao;

public class UserCustomDaoImpl extends AbstractDao implements IUserCustomDao {
    public UserCustomDaoImpl(DaoMetaDataFactory daoMetaDataFactory) {
        super(daoMetaDataFactory);
    }
    
    void execPartialSQL(Map<Long, IUser> userMap, String column, String[] keywords, int offset, int limit) {
        StringBuilder sqlBuilder = new StringBuilder();
        List<Object> argList = new ArrayList<Object>();

        sqlBuilder.append("SELECT\n");
        sqlBuilder.append("    a.*,\n");
        sqlBuilder.append("    b.serverFileId,\n");
        sqlBuilder.append("    b.name,\n");
        sqlBuilder.append("    b.mime,\n");
        sqlBuilder.append("    b.size,\n");
        sqlBuilder.append("    b.charset,\n");
        sqlBuilder.append("    b.width,\n");
        sqlBuilder.append("    b.height,\n");
        sqlBuilder.append("    b.createdTime AS serverFileCreatedTime,\n");
        sqlBuilder.append("    c.*\n");
        sqlBuilder.append("FROM\n");
        sqlBuilder.append("    (users AS a LEFT JOIN\n");
        sqlBuilder.append("     serverfiles AS b ON a.profileImageId=b.serverFileId) LEFT JOIN\n");
        sqlBuilder.append("     devices AS c ON a.userId=c.userId\n");
        sqlBuilder.append("WHERE\n");
        sqlBuilder.append("    a.remove=false AND\n");
        for (int i = 0; i < keywords.length; i++) {
            sqlBuilder.append("    ");
            sqlBuilder.append(column);
            sqlBuilder.append(" LIKE ?");
            if (i + 1 < keywords.length) {
                sqlBuilder.append("AND");
            }
            sqlBuilder.append("\n");
            keywords[i] = ShovelUtil.escape(keywords[i]);
            argList.add("%" + keywords[i] + "%");
        }
        sqlBuilder.append("ORDER BY\n");
        sqlBuilder.append("    a.userId DESC\n");
        sqlBuilder.append("LIMIT ?,?");
        argList.add(offset);
        argList.add(limit);

        Object[] args = argList.toArray(new Object[argList.size()]);
        IUser[] users = (IUser[])getEntityManager().findArray(sqlBuilder.toString(), args);
        
        for (IUser user : users) {
            userMap.put(user.getUserId(), user);
        }
    }
    public IUser[] search(String[] keywords, int offset, int limit) {
        Map<Long, IUser> userMap = new HashMap<Long, IUser>();
        execPartialSQL(userMap, "a.displayName", keywords, offset, limit);
        execPartialSQL(userMap, "a.foreignKey", keywords, offset, limit);
        execPartialSQL(userMap, "a.location", keywords, offset, limit);
        
        Collection<IUser> userCollection = userMap.values();
        IUser[] users = userCollection.toArray(new IUser[userCollection.size()]);
        return (IUser[])ArrayUtils.subarray(users, 0, limit);
    }
}
