const log      = require('../utils/log.utils');          // Log Helper

const dbUser = process.env.OWL_DB_USER || "owl"
const dbPass = process.env.OWL_DB_PASS || "twittwoo"
const dbName = process.env.OWL_DB_NAME || "owlboard"
const dbPort = process.env.OWL_DB_PORT || 27017
const dbHost = process.env.OWL_DB_HOST || "localhost"
const uri = `mongodb://${dbUser}:${dbPass}@${dbHost}:${dbPort}`;

const { MongoClient } = require('mongodb');

const client = new MongoClient(uri);
const db = client.db(dbName);

async function dropCollection(coll){
    await client.connect();

    // check if collection contains any documents, if it doesn't, it is either empty or non-existent - it doesn't need dropping.
    var collection = db.collection(coll);
    var count = await collection.countDocuments();
    log.out(`DbAccess.dropCollection: Collection '${coll}' contains ${count} documents`)
    if (count == 0) {
        log.out(`DbAccess.dropCollection: Collection '${coll}' is empty.  Do not need to drop`)
    } else {
        log.out(`DbAccess.dropCollection: dropping collection: '${coll}'`)
        db.dropCollection(coll);
        log.out(`DbAccess.dropCollection: dropped collection: '${coll}'`)
    }
    // ALTERNATIVE METHOD - Appears to not be needed:
    // This code returns and prints an array containing an object for each existing collection.
//    var cols = await db.listCollections().toArray()
//    log.out(`dbAccess.dropCollection: Existing collections: ${JSON.stringify(cols)}`)
    // If (any object in the Array contains name:{coll} then exsists.  If not doesn't exist.)
}

async function putCorpus(data){
    log.out("DbAccess.putCorpus: Uploading CORPUS data to database")
    await client.connect();
    try {
        var coll = db.collection("corpus");
        await coll.insertMany(data);
    } catch (error) {
        log.out("DbAccess.putCorpus: Error uploading Corpus data to database")
        log.out(error)
    }
};

async function putStations(data){
    log.out("DbAccess.putStations: Uploading Stations data to database")
    await client.connect();
    try {
        var coll = db.collection("stations");
        coll.insertMany(data);
    } catch (error) {
        log.out("DbAccess.putStations: Error uploading Stations data to database")
        log.out(error)
    }
};

async function updateMeta(type, target, unixTime){
    await client.connect();
    var coll = db.collection("meta");
    var filter = {type: type, target: target};
    var update = {$set:{updated: unixTime}};
    var options = {upsert: true};  // If document isn't present will insert.
    try {
        var result = await coll.updateOne(filter,update,options)
        log.out(`dbAccessServices.updateMeta: ${JSON.stringify(result)}`)
        log.out(`dbAccessServices.updateMeta: meta for '${target}' updated`)
    } catch (err) {
        log.out(`dbAccessServices.updateMeta: Unable to update meta for '${target}'`)
        log.out(err)
    }
}

async function query(collection, query){
    await client.connect();
    log.out(`dbAccess.query: Connecting to collection: '${collection}'`)
    var qcoll = db.collection(collection);
    var qcursor = qcoll.find(query)
    qcursor.project({_id: 0})
    log.out(`dbAccess.query: Running Query: ${JSON.stringify(query)}`)
    var qresult = await qcursor.toArray();
    return qresult;
}

module.exports = {
    putCorpus,
    putStations,
    dropCollection,
    updateMeta,
    query
}