package dst.ass1.doc.impl;

import com.mongodb.client.MapReduceIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import dst.ass1.doc.IDocumentQuery;
import dst.ass1.jpa.util.Constants;
import org.bson.Document;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Filters.regex;

public class DocumentQuery implements IDocumentQuery {
    private MongoDatabase db;

    public DocumentQuery(MongoDatabase db) {
        this.db = db;
    }

    @Override
    public Document findByMaterialId(Long materialId) {
        MongoCollection<Document> coll = db.getCollection(Constants.COLL_MATERIAL_DATA);
        return coll.find(eq(Constants.I_MATERIAL, materialId)).first();
    }

    @Override
    public List<Long> findIdsByType(String typeSubstring) {
        MongoCollection<Document> coll = db.getCollection(Constants.COLL_MATERIAL_DATA);
        List<Long> ret = new ArrayList<>();
        for (Document doc : coll.find(regex(Constants.M_MATERIAL_TYPE, ".*" + Pattern.quote(typeSubstring) + ".*"))) {
            ret.add(Long.valueOf("" + doc.get(Constants.I_MATERIAL)));
        }

        return ret;
    }

    @Override
    public List<Document> getDocumentStatistics() {
        MongoCollection coll = db.getCollection(Constants.COLL_MATERIAL_DATA);

        String map = "function(){if(this.type=='quiz')emit(this.quiz_type,this.questions.length);}";
        String reduce = "function(key, values) { " +
                "var result = 0;" +
                "values.forEach(function(value){result += value;});" +
                "return result;}";

        MapReduceIterable<Document> iter = coll.mapReduce(map, reduce);
        ArrayList<Document> a = iter.into(new ArrayList<Document>());
        return a;
    }

}