package com.conveyal.taui.persistence;

import com.conveyal.taui.AnalystConfig;
import com.conveyal.taui.models.Bundle;
import com.conveyal.taui.models.Model;
import com.conveyal.taui.models.Modification;
import com.conveyal.taui.models.Scenario;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoURI;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.mongojack.JacksonDBCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.Map;

/**
 * Manages a single connection to MongoDB for the entire TAUI server process.
 */
public class Persistence {
    private static final Logger LOG = LoggerFactory.getLogger(Persistence.class);

    // TODO deprecated but needed for MongoJack
    private static Mongo mongo;
    private static DB db;

    public static MongoMap<Modification> modifications;
    public static MongoMap<Scenario> scenarios;
    public static MongoMap<Bundle> bundles;

    public static void initialize () {
        LOG.info("Connecting to MongoDB");
        // allow configurable db connection params

        if (AnalystConfig.databaseUri != null) {
            mongo = new Mongo(new MongoURI(AnalystConfig.databaseUri));
            LOG.info("Connecting to remote MongoDB instance");
        }
        else {
            LOG.info("Connecting to local MongoDB instance");
            mongo = new Mongo();
        }

        db = mongo.getDB(AnalystConfig.databaseName);

        modifications = getTable("modifications", Modification.class);
        scenarios = getTable("scenarios", Scenario.class);
        bundles = getTable("bundles", Bundle.class);
    }

    /** connect to a table using MongoJack */
    private static <V extends Model> MongoMap<V> getTable (String name, Class clazz) {
        DBCollection collection = db.getCollection(name);
        JacksonDBCollection<V, String> coll = JacksonDBCollection.wrap(collection, clazz, String.class);
        return new MongoMap<>(coll);
    }
}

@@ -354,16 +354,90 @@
 Client;%0A
+import com.mongodb.MongoClientOptions;%0Aimport com.mongodb.MongoClientURI;%0A
 import c
@@ -453,24 +453,24 @@
 b.MongoURI;%0A
-
 import com.m
@@ -961,16 +961,22 @@
 ic Mongo
+Client
  mongo;%0A
@@ -1330,24 +1330,141 @@
  != null) %7B%0A
+            MongoClientOptions.Builder builder = MongoClientOptions.builder()%0A                    .sslEnabled(true);%0A
             
@@ -1480,16 +1480,22 @@
 ew Mongo
+Client
 (new Mon
@@ -1496,16 +1496,22 @@
 ew Mongo
+Client
 URI(Anal
@@ -1531,16 +1531,25 @@
 abaseUri
+, builder
 ));%0A    
@@ -1686,32 +1686,32 @@
 oDB instance%22);%0A
-
             mong
@@ -1723,16 +1723,22 @@
 ew Mongo
+Client
 ();%0A    

use non-deprecated MongoDB classes wherever possible.