package ru.yandex.canvas.repository.video;

import java.util.function.Supplier;

import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import ru.yandex.canvas.model.video.overlay.OverlayBundle;
import ru.yandex.canvas.model.video.overlay.OverlayCreative;
import ru.yandex.direct.tracing.Trace;
import ru.yandex.direct.tracing.TraceProfile;

public class OverlayCreativesRepository {
    private MongoOperations mongoOperations;

    public OverlayCreativesRepository(MongoOperations mongoOperations) {
        this.mongoOperations = mongoOperations;
    }

    private <REC> REC databaseWrapper(Supplier<REC> wrapper, String opName) {
        try (TraceProfile profile = Trace.current().profile("db:" + opName, "canvas_overlay_creatives")) {
            return wrapper.get();
        }
    }

    private void databaseWrapper(Runnable wrapper, String opName) {
        try (TraceProfile profile = Trace.current().profile("db:" + opName, "canvas_overlay_creatives")) {
            wrapper.run();
        }
    }

    public void insert(OverlayBundle record) {
        databaseWrapper(() -> mongoOperations.insert(record), "insert_bundle");
    }

    public void insertCreative(OverlayCreative record) {
        databaseWrapper(() -> mongoOperations.insert(record), "insert_creative");
    }

    public OverlayBundle findById(String overlayId, Long clientId) {
        return databaseWrapper(() -> mongoOperations.findOne(
                new QueryBuilder().withId(overlayId).withClientId(clientId).build(),
                OverlayBundle.class), "find");
    }

    public static class QueryBuilder extends QueryBuilderBase<QueryBuilder> {
        public QueryBuilder withId(String id) {
            criteries.add(Criteria.where("_id").is(id));
            return this;
        }

        public QueryBuilder withClientId(Long clientId) {
            criteries.add(Criteria.where("client_id").is(clientId));
            return this;
        }

        @Override
        public Query build() {
            Query query = new Query();
            for (Criteria criteria : criteries) {
                query.addCriteria(criteria);
            }
            return query;
        }
    }
}
