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

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

import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.data.WebmasterUser;
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;

@Repository
public class UserPinnedHostsYDao extends AbstractYDao {
    private static final String TABLE_NAME = "user_pinned_hosts";

    protected UserPinnedHostsYDao() {
        super(PREFIX_USER, TABLE_NAME);
    }

    public void savePinnedHost(WebmasterUser user, WebmasterHostId hostId) {
        upsert(F.HOST_ID.value(hostId), F.USER_ID.value(user.getUserId()))
                .execute();
    }

    public void deletePinnedHost(WebmasterUser user, WebmasterHostId hostId) {
        delete()
                .where(F.HOST_ID.eq(hostId))
                .and(F.USER_ID.eq(user.getUserId()))
                .execute();
    }

    public void deleteForUser(WebmasterUser user) {
        delete()
                .where(F.USER_ID.eq(user.getUserId()))
                .execute();
    }

    public List<WebmasterHostId> listPinnedHosts(WebmasterUser user) {
        return select(F.HOST_ID)
                .where(F.USER_ID.eq(user.getUserId()))
                .queryForList(Pair.of(F.HOST_ID, Function.identity()));
    }

    public boolean isHostPinned(WebmasterUser user, WebmasterHostId hostId) {
        WebmasterHostId resultId = select(F.HOST_ID)
                .where(F.HOST_ID.eq(hostId))
                .and(F.USER_ID.eq(user.getUserId()))
                .queryOne();
        return resultId != null;
    }

    public void forEachHost(Consumer<Pair<Long, WebmasterHostId>> consumer) {
        streamReader(DataMapper.create(F.USER_ID, F.HOST_ID, Pair::of), consumer);
    }

    private static class F {
        private static final Field<WebmasterHostId> HOST_ID = Fields.hostIdField("host_id");
        private static final Field<Long> USER_ID = Fields.longField("user_id");
    }
}
