package ru.yandex.wmconsole.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import ru.yandex.common.util.collections.Cu;
import ru.yandex.misc.db.q.InsertSqlQueryBuilder;
import ru.yandex.misc.db.q.SqlQuery;
import ru.yandex.wmconsole.data.BadSoftwareNotificationInfo;
import ru.yandex.wmconsole.data.partition.WMCPartition;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.UserException;
import ru.yandex.wmtools.common.servantlet.AbstractServantlet;
import ru.yandex.wmtools.common.service.AbstractDbService;

import java.net.IDN;
import java.net.URL;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

/**
 * User: azakharov
 * Date: 08.08.14
 * Time: 13:59
 */
public class BadSoftwareNotificationService extends AbstractDbService implements GroupableByHostService<BadSoftwareNotificationInfo> {

    private static Logger log = LoggerFactory.getLogger(BadSoftwareNotificationService.class);

    public Long saveNotificationInfo(final Long hostId, final String url, final Date receiveTime) throws InternalException {
        SqlQuery query = new InsertSqlQueryBuilder().tableName("tbl_notification_bad_software")
                .columnValue("host_id", hostId)
                .columnValue("url", url)
                .columnValue("receive_time", receiveTime).toSqlQuery();
        Number issueId = getJdbcTemplate(WMCPartition.nullPartition()).insertSingle(query.sql(), query.args());
        return issueId.longValue();
    }

    @Override
    public BadSoftwareNotificationInfo getSingleNotification(Long id) throws InternalException {
        String q = "SELECT host_id, url, receive_time FROM tbl_notification_bad_software " +
                   "WHERE issue_id = ?";
        ParameterizedRowMapper<BadSoftwareNotificationInfo> m = new ParameterizedRowMapper<BadSoftwareNotificationInfo>() {
            @Override
            public BadSoftwareNotificationInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
                return new BadSoftwareNotificationInfo(rs.getLong("host_id"), rs.getTimestamp("receive_time"), rs.getString("url"));
            }
        };
        List<BadSoftwareNotificationInfo> res = getJdbcTemplate(WMCPartition.nullPartition()).query(q, m, id);
        if (res.isEmpty()) {
            return null;
        }
        return convertPunycodeUrlToUnicode(Cu.first(res));
    }

    private BadSoftwareNotificationInfo convertPunycodeUrlToUnicode(BadSoftwareNotificationInfo notification) {
        String url = notification.getUrl();
        try {
            URL u = AbstractServantlet.prepareUrl(url, true);
            String beautifulUrl = u.toExternalForm();
            beautifulUrl = beautifulUrl.replaceFirst(u.getHost(), IDN.toUnicode(u.getHost()));
            return new BadSoftwareNotificationInfo(notification.getHostId(), notification.getReceiveTime(), beautifulUrl);
        } catch (UserException e) {
            log.error("Skip punycode url " + url + " because of validation problem", e);
            return notification;
        }
    }
}
