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.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joda.time.DateTime;
import org.springframework.stereotype.Repository;
import ru.yandex.webmaster3.core.data.WebmasterHostGeneration;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.storage.host.dao.HostsYDao;
import ru.yandex.webmaster3.storage.host.moderation.regions.HostModeratedRegions;
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.function.Consumer;

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

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

    public void setHostRegions(WebmasterHostId hostId, @NotNull Set<Integer> regions, @NotNull Set<Integer> prevRegions) {
        upsert(
                F.HOST_ID.value(hostId),
                F.REGIONS.value(regions),
                F.PREV_REGIONS.value(prevRegions),
                F.CREATED.value(DateTime.now())
        ).execute();
    }

    @Nullable
    public HostModeratedRegions getHostRegions(WebmasterHostId hostId) {
        return select(MAPPER)
                .where(F.HOST_ID.eq(hostId))
                .queryOne();
    }

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

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

        static final Field<WebmasterHostId> HOST_ID = Fields.hostIdField("host_id");
        static final Field<Set<Integer>> REGIONS = Fields.setField("regions", INT_SET_REFERENCE);
        static final Field<Set<Integer>> PREV_REGIONS = Fields.setField("prev_regions", INT_SET_REFERENCE);
        static final Field<DateTime> CREATED = Fields.jodaDateTimeField("created");
    }

    private static final DataMapper<HostModeratedRegions> MAPPER = DataMapper.create(
        F.HOST_ID, F.REGIONS, F.PREV_REGIONS, F.CREATED, HostModeratedRegions::new
    );
}
