package cn.reghao.tnb.sb.db.mongo;

import com.mongodb.MongoBulkWriteException;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.*;
import com.mongodb.client.model.InsertManyOptions;
import com.mongodb.client.result.InsertManyResult;
import org.bson.Document;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author reghao
 * @date 2021-12-29 14:35:24
 */
public class MongoDbClient {
    //private MongoConverter mongoConverter;
    private final MongoCollection<Document> collection;

    public MongoDbClient(/*MongoConverter mongoConverter*/) {
        String host = "127.0.0.1";
        String username = "dev";
        String password = "Dev@123456";
        String authDb = "admin";

        MongoCredential credential = MongoCredential.createCredential(username, authDb, password.toCharArray());
        MongoClient client = MongoClients.create(
                MongoClientSettings.builder()
                        .credential(credential)
                        .applyToClusterSettings(
                                builder -> builder.hosts(Collections.singletonList(new ServerAddress(host))))
                        .build());

        String database = "reghao_spider_rdb";
        MongoDatabase db = client.getDatabase(database);
        this.collection = db.getCollection("UnparsedData");
    }

    public void getAndConvert() {
        Document query = new Document();
        query.append("parser", "AnswersDataParser");

        List<Document> list = new ArrayList<>();
        FindIterable<Document> iterable = collection.find(query);
        iterable.forEach(document -> {
            parse(document, list);
        });
        updateAll(list);
    }

    private void parse(Document document, List<Document> list) {
        //UnparsedData unparsedData = mongoConverter.read(UnparsedData.class, document);
        //unparsedData.setParser("AnswersJsonDataParser");

        Document doc = new Document();
        //mongoConverter.write(unparsedData, doc);
        list.add(doc);
        if (list.size() > 10000) {
            updateAll(list);
            list.clear();
        }
    }

    public void saveAll(List<Document> list) {
        InsertManyOptions options = new InsertManyOptions();
        options.ordered(false);
        try {
            InsertManyResult result = collection.insertMany(list, options);
        } catch (MongoBulkWriteException e) {
            e.getMessage();
        }
    }

    public void updateAll(List<Document> list) {
        try {
            list.forEach(document -> {
                Document filter = new Document();
                filter.put("url", document.get("url"));
                collection.findOneAndReplace(filter, document);
            });
        } catch (Exception e) {
            e.getMessage();
        }
    }

    public void getAndProcess() {
        Document query = new Document();
        query.append("site", "bilibili");
        //query.append("parser", "parser");
        collection.find(query).noCursorTimeout(true).forEach(new DataConsumer());
    }

    static class DataConsumer implements Consumer<Document> {
        @Override
        public void accept(Document document) {
            System.out.println();
        }
    }

    public static void main(String[] args) {
        MongoDbClient client = new MongoDbClient();
        client.getAndProcess();
    }
}
