package ru.yandex.wmtools.common.service;

import ru.yandex.common.framework.pager.Pager;
import ru.yandex.wmtools.common.data.IHistoryAction;
import ru.yandex.wmtools.common.data.IHistoryObjectType;
import ru.yandex.wmtools.common.data.info.HistoryInfo;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.util.SqlUtil;

import java.util.List;

/**
 * User: baton
 * Date: 29.06.2007
 * Time: 16:42:21
 */
public abstract class HistoryService extends AbstractDbService {
    public static final int MAXIMAL_NEWVALUE_LENGTH = 20;
    public static final String ELLIPSIS = "...";

    private IUserInfoService userInfoService;
    protected IUserInfoService getUserInfoService() {
        return userInfoService;
    }
    public void setUserInfoService(IUserInfoService userInfoService) {
        this.userInfoService = userInfoService;
    }

    public void addEvents(Long realUserId, Long virtualUserId, IHistoryAction historyAction,
                           IHistoryObjectType historyObjectType, Long... objectIds) throws InternalException {
        for (Long objectId : objectIds) {
            addSingleEvent(realUserId, virtualUserId, historyAction, historyObjectType, objectId, null);
        }
    }

    public void addEvents(Long realUserId, Long virtualUserId, String newValue, IHistoryAction historyAction,
                           IHistoryObjectType historyObjectType, Long... objectIds) throws InternalException {
        for (Long objectId : objectIds) {
            addSingleEvent(realUserId, virtualUserId, historyAction, historyObjectType, objectId, newValue);
        }
    }

    private void addSingleEvent(Long realUserId, Long virtualUserId, IHistoryAction historyAction,
                                  IHistoryObjectType historyObjectType, Long objectId, String newValue) throws InternalException {
        if ((newValue != null) && (newValue.length() > MAXIMAL_NEWVALUE_LENGTH)) {
            newValue = newValue.substring(0, MAXIMAL_NEWVALUE_LENGTH - ELLIPSIS.length()) + ELLIPSIS;
        }

        addHistoryQuery(realUserId, virtualUserId, historyAction, historyObjectType, objectId, newValue);
    }

    protected abstract void addHistoryQuery(Long userId, Long virtualUserId, IHistoryAction historyAction,
            IHistoryObjectType historyObjectType, Long objectId, String newValue) throws InternalException;

    public List<HistoryInfo> getHistoryListForObject(long objectId, Pager pager, IHistoryObjectType ... types) throws InternalException {
        int[] values = new int[types.length];
        int cnt = 0;
        for (IHistoryObjectType type : types) {
            values[cnt++] = type.getValue();
        }

        String countSql = String.format(
                getHistoryListCountWithPlaceholders(),
                SqlUtil.createQuestionMarks(cnt)
        );

        String selectSql = String.format(
                getHistoryListSelectWithPlaceholders(),
                SqlUtil.createQuestionMarks(cnt),
                "%1$s"
        );

        Object[] params = SqlUtil.prepareLastParams(values, objectId);

        return getHistoryListQuery(countSql, selectSql, objectId, pager, params);
    }

    protected abstract List<HistoryInfo> getHistoryListQuery(String countSql, String selectSql, long objectId, Pager pager, Object[] params) throws InternalException;

    protected abstract String getHistoryListSelectWithPlaceholders();

    protected abstract String getHistoryListCountWithPlaceholders();
}
