mongodb = require('mongodb')
ObjectId = mongodb.ObjectId
MongoClient = mongodb.MongoClient
Collection = mongodb.Collection
Cursor = mongodb.Cursor

Promise = require 'bluebird'

log = require('./log')
config = require("./config")

dbQs = {}

connectDb = (tag, url)->
    return dbQs[tag] if dbQs[tag]?

    connect = Promise.promisify MongoClient.connect
    q = connect url
    q.then (db)->
        dbQs[tag] = q
        db.on 'close', ->
            log.system.info 'Mongo DB closed'
            delete dbQs[tag]
        db.on 'error', (e)->
            log.system.error e, 'Mongo DB error'
            delete dbQs[tag]
        db.on 'reconnect', ->
            log.system.info 'Mongo DB reconnect'

    return q

exports.db = -> connectDb 'stats', config.mongoUrl
exports.dbAccount = -> connectDb 'account', config.accountMongoUrl

exports.gDispose = ->
    for key, q of dbQs
        try
            db = yield q
            yield db.close()
        catch e
            log.system.error e, 'gDispose'

exports.insert = Promise.promisify(Collection.prototype.insert)
exports.insertOne = Promise.promisify(Collection.prototype.insertOne)
exports.insertMany = Promise.promisify(Collection.prototype.insertMany)

exports.updateOne = Promise.promisify(Collection.prototype.updateOne)
exports.updateMany = Promise.promisify(Collection.prototype.updateMany)

exports.deleteOne = Promise.promisify(Collection.prototype.deleteOne)
exports.deleteMany = Promise.promisify(Collection.prototype.deleteMany)

exports.findAndModify = Promise.promisify(Collection.prototype.findAndModify)

exports.findOneAndUpdate = Promise.promisify(Collection.prototype.findOneAndUpdate)
exports.findOneAndDelete = Promise.promisify(Collection.prototype.findOneAndDelete)
exports.findOneAndReplace = Promise.promisify(Collection.prototype.findOneAndReplace)

# 不能批量删除后返回被删除的所有文档

exports.findOne = Promise.promisify(Collection.prototype.findOne)

exports.count = Promise.promisify(Collection.prototype.count)

exports.toArray = Promise.promisify(Cursor.prototype.toArray)

exports.createIndex = Promise.promisify(Collection.prototype.createIndex)

# 返回值是ObjectId
exports.getInsertedIdObject = (insertResponse)->
    return insertResponse?.insertedId || null

ErrorCodes =
    Index: 11000

exports.isIndexConflictError = (e)->
    return e.code == ErrorCodes.Index


exports.stringToObjectId = (string)->
    return null unless string
    if string instanceof ObjectId
        string
    else
        new ObjectId string

exports.stringToObjectIdSilently = (string)->
    return null unless string
    if string instanceof ObjectId
        string
    else
        try
            new ObjectId string
        catch
            null