package ru.yandex.webmaster3.storage.host.moderation.regions.dao;

import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.DateTime;
import org.springframework.stereotype.Repository;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.storage.host.moderation.regions.HostRegionsModerationYtRequest;
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;

import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @author leonidrom
 */
@Repository
public class HostRegionsModerationYtRequestsYDao extends AbstractYDao {
    private static final String TABLE_NAME = "host_regions_mod_yt_reqs";

    public HostRegionsModerationYtRequestsYDao() {
        super(PREFIX_REGION, TABLE_NAME);
    }

    public void storeRequest(HostRegionsModerationYtRequest request) {
        upsert(
                F.REQUEST_ID.value(request.getRequestId()),
                F.HOST_ID.value(request.getHostId()),
                F.CREATED_DATE.value(request.getCreatedDate()),
                F.CURRENT_REGIONS.value(request.getCurrentRegions()),
                F.REQUESTED_REGIONS.value(request.getRequestedRegions()),
                F.AUTO_MODERATED_REGIONS.value(request.getAutoModeratedRegions()),
                F.NEED_MODERATION_REGIONS.value(request.getNeedModerationRegions()),
                F.EVIDENCE_URL.value(request.getEvidenceUrl()))
        .execute();
    }

    public void deleteRequests(List<UUID> batch) {
        batchDelete(DELETE_VALUE_MAPPER, batch).execute();
    }

    public void forEach(Consumer<HostRegionsModerationYtRequest> consumer) {
        streamReader(MAPPER, consumer);
    }

    private static final class F {
        private static final TypeReference<Set<Integer>> INTEGER_SET = new TypeReference<>() {
        };

        private static final Field<UUID> REQUEST_ID = Fields.uuidField("request_id");
        private static final Field<WebmasterHostId> HOST_ID = Fields.hostIdField("host_id");
        private static final Field<Set<Integer>> CURRENT_REGIONS = Fields.setField("current_regions", INTEGER_SET);
        private static final Field<Set<Integer>> REQUESTED_REGIONS = Fields.setField("requested_regions", INTEGER_SET);
        private static final Field<Set<Integer>> AUTO_MODERATED_REGIONS = Fields.setField("auto_moderated_regions", INTEGER_SET);
        private static final Field<Set<Integer>> NEED_MODERATION_REGIONS = Fields.setField("need_moderation_regions", INTEGER_SET);
        private static final Field<DateTime> CREATED_DATE = Fields.jodaDateTimeField("created_date");
        private static final Field<String> EVIDENCE_URL = Fields.stringField("evidence_url").makeOptional();
    }

    private static final DataMapper<HostRegionsModerationYtRequest> MAPPER = DataMapper.create(F.REQUEST_ID, F.HOST_ID,
            F.CREATED_DATE, F.CURRENT_REGIONS, F.REQUESTED_REGIONS, F.AUTO_MODERATED_REGIONS, F.NEED_MODERATION_REGIONS, F.EVIDENCE_URL,
            HostRegionsModerationYtRequest::new);

    private static final ValueDataMapper<UUID> DELETE_VALUE_MAPPER = ValueDataMapper.create2(
        Pair.of(F.REQUEST_ID, Function.identity())
    );
}
