package ru.yandex.webmaster3.storage.checklist.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.apache.commons.lang3.tuple.Pair;
import org.apache.curator.shaded.com.google.common.collect.Lists;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.checklist.data.SiteProblemTypeEnum;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.storage.util.ydb.AbstractYDao;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.DataMapper;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.Field;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.Fields;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.ValueDataMapper;


/**
 * @author kravchenko99
 * @date 8/3/21
 */

@Repository
public class HostsWithUrlAlertYDao extends AbstractYDao {
    private static final String TABLE_NAME = "hosts_with_url_alert";
    private static final int BATCH_SIZE = 5000;

    public HostsWithUrlAlertYDao() {
        super(PREFIX_CHECKLIST, TABLE_NAME);
    }



    public List<WebmasterHostId> getHostsByProblemType(SiteProblemTypeEnum type) {
        List<WebmasterHostId> list = new ArrayList<>();
        forEach(x -> {
            if (x.getValue() == type) {
                list.add(x.getKey());
            }
        });
        return list;
    }

    public void forEach(Consumer<Pair<WebmasterHostId, SiteProblemTypeEnum>> consumer) {
        streamReader(MAPPER, consumer);
    }

    public void delete(Collection<WebmasterHostId> hostIds, SiteProblemTypeEnum type) {
        List<Pair<WebmasterHostId, SiteProblemTypeEnum>> items =
                hostIds.stream().map(x -> Pair.of(x, type)).collect(Collectors.toList());
        batchDelete(VALUE_MAPPER, items).execute();
    }

    public void insert(Collection<WebmasterHostId> hostIds, SiteProblemTypeEnum problemType) {
        Lists.partition(hostIds.stream().map(hostId -> Pair.of(hostId, problemType))
                        .collect(Collectors.toList()), BATCH_SIZE)
                .forEach(items -> batchInsert(VALUE_MAPPER, items).execute());
    }

    private static final ValueDataMapper<Pair<WebmasterHostId, SiteProblemTypeEnum>> VALUE_MAPPER = ValueDataMapper.create2(
            Pair.of(F.HOST_ID, Pair::getKey),
            Pair.of(F.PROBLEM_TYPE, Pair::getValue)
    );
    private static final DataMapper<Pair<WebmasterHostId, SiteProblemTypeEnum>> MAPPER = DataMapper.create(
            F.HOST_ID, F.PROBLEM_TYPE, Pair::of
    );

     private  interface F {
         Field<SiteProblemTypeEnum> PROBLEM_TYPE = Fields.intEnumField("problem_type", SiteProblemTypeEnum.R);
         Field<WebmasterHostId> HOST_ID = Fields.hostIdField("host_id");
    }
}
