package ru.yandex.webmaster.common.contentpreview.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;

import ru.yandex.misc.db.q.SqlCondition;
import ru.yandex.webmaster.common.contentpreview.ContentPreviewSettings;
import ru.yandex.webmaster.common.contentpreview.ContentPreviewState;
import ru.yandex.webmaster.common.contentpreview.ContentPreviewType;
import ru.yandex.wmconsole.data.info.BriefHostInfo;
import ru.yandex.wmconsole.data.partition.WMCPartition;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.service.AbstractDbService;

/**
 * <pre>
 * CREATE TABLE IF NOT EXISTS tbl_content_preview_settings (
 *     host_id  BIGINT(20) NOT NULL
 *   , preview_type TINYINT NOT NULL
 *   , preview_state TINYINT NOT NULL
 *
 *   , PRIMARY KEY (host_id, preview_type)
 *   , FOREIGN KEY (host_id) REFERENCES tbl_hosts (host_id) ON DELETE CASCADE
 * ) ENGINE=InnoDB;
 * </pre>
 *
 * @author aherman
 */
public class TblContentPreviewSettingsDao extends AbstractDbService {
    public void save(List<ContentPreviewSettings> contentPreviewSettings) throws InternalException {
        Validate.isTrue(!contentPreviewSettings.isEmpty(), "Settings list must not be empty");
        String q = "REPLACE INTO tbl_content_preview_settings(host_id, preview_type, preview_state) VALUES " +
                StringUtils.repeat("(?, ?, ?)", ",", contentPreviewSettings.size());
        List<Object> params = new ArrayList<>(contentPreviewSettings.size() * 3);
        for (ContentPreviewSettings contentPreviewSetting : contentPreviewSettings) {
            params.add(contentPreviewSetting.getHostId());
            params.add(contentPreviewSetting.getType().value());
            params.add(contentPreviewSetting.getState().value());
        }
        getJdbcTemplate(WMCPartition.nullPartition()).update(q, params.toArray());
    }

    public void remove(List<ContentPreviewSettings> contentPreviewSettings) throws InternalException {
        Validate.isTrue(!contentPreviewSettings.isEmpty(), "Settings list must not be empty");
        SqlCondition c = null;
        for (ContentPreviewSettings setting : contentPreviewSettings) {
            SqlCondition clause = SqlCondition.all(
                    SqlCondition.column("host_id").eq(setting.getHostId()),
                    SqlCondition.column("preview_type").eq(setting.getType().value())
            );
            if (c == null) {
                c = clause;
            } else {
                c = c.or(clause);
            }
        }
        String q = "DELETE FROM tbl_content_preview_settings WHERE " + c.sql();
        getJdbcTemplate(WMCPartition.nullPartition()).update(q, c.args().toArray());
    }

    public List<ContentPreviewSettings> load(BriefHostInfo hostInfo) throws InternalException {
        String q = "SELECT * FROM tbl_content_preview_settings WHERE host_id = ?";
        return getJdbcTemplate(WMCPartition.nullPartition()).query(q, getMapper(), hostInfo.getId());
    }

    public List<ContentPreviewSettings> loadAll() throws InternalException {
        String q = "SELECT * FROM tbl_content_preview_settings ORDER BY host_id";
        return getJdbcTemplate(WMCPartition.nullPartition()).query(q, getMapper());
    }

    private ParameterizedRowMapper<ContentPreviewSettings> getMapper() {
        return new ParameterizedRowMapper<ContentPreviewSettings>() {
            @Override
            public ContentPreviewSettings mapRow(ResultSet rs, int rowNum) throws SQLException {
                ContentPreviewType previewType = ContentPreviewType.R.fromValueOrUnknown(rs.getInt("preview_type"));
                ContentPreviewState previewState = ContentPreviewState.R.fromValueOrUnknown(
                        rs.getInt("preview_state"));
                long hostId = rs.getLong("host_id");
                return new ContentPreviewSettings(hostId, previewType, previewState);
            }
        };
    }
}
