﻿"use strict";

const _ = require("lodash");
const fs = require("fs-extra");
const path = require("path");
const async = require("async");
const config = require("config");
const cp = require("child_process");
const mongoose = require("mongoose");

let _connected = false;

/**
 * 启动数据库 Server。
 * @param {Function(err)} [p_callback]
 */
module.exports.start = function (p_callback)
{
    const dbpath = path.resolve(__dirname, "../db");
    _prepareMongoDB(dbpath, (err1) =>
    {
        if (err1)
        {
            p_callback(err1);
        }
        else
        {
            const timer = setTimeout(p_callback, 2000);
            cp.exec(`mongod --dbpath "${dbpath}"`, (err2) =>
            {
                if (err2)
                {
                    clearTimeout(timer);
                    p_callback(err2);
                }
            });
        }
    });
};

/**
 * 连接数据库。
 * @param {Function(err)} [p_callback]
 */
module.exports.connect = function (p_callback)
{
    // TODO: check if correct.
    console.log(`Connecting database: ${process.env.MONGODB_CONNECTION || config.db}`);
    if (process.env.MONGODB_CONNECTION)
    {
        const db = mongoose.createConnection();
        db.openSet(
            `mongodb://${process.env.MONGODB_CONNECTION}`,
            {
                server: {
                    auto_reconnect: config.auto_reconnect,
                    poolSize: config.poolSize
                }
            },
            (err) =>
            {
                _connected = !err;
                _monitor();
                if (_.isFunction(p_callback))
                {
                    p_callback(err);
                }
            }
        );
    }
    else
    {
        mongoose.connect(
            config.db,
            {
                server: {
                    auto_reconnect: config.auto_reconnect,
                    poolSize: config.poolSize
                }
            },
            (err) =>
            {
                _connected = !err;
                _monitor();
                if (_.isFunction(p_callback))
                {
                    p_callback(err);
                }
            }
        );
    }
};

/**
 * 检查数据库是否已连接。
 */
module.exports.connected = function ()
{
    return _connected;
};

/**
 * 删除所有集合。
 * @param {Function(err)} [p_callback]
 */
module.exports.dropAllCollections = function (p_callback)
{
    async.each(
        mongoose.connection.collections,
        (collection, done) =>
        {
            collection.drop(done);
        },
        (err) =>
        {
            if (_.isFunction(p_callback))
            {
                if (!err || err.message === "ns not found")
                {
                    p_callback();
                }
                else
                {
                    p_callback(err);
                }
            }
        }
    );
};

/**
 * 监控数据库状态。
 */
function _monitor()
{
    const db = mongoose.connection.db;
    if (db)
    {
        db.on("reconnect", () =>
        {
            _connected = true;
        });

        db.on("close", () =>
        {
            _connected = false;
        });

        db.on("error", () =>
        {
            _connected = false;
        });
    }
}

function _prepareMongoDB(p_dbpath, p_callback)
{
    fs.mkdirs(p_dbpath, (err1) =>
    {
        if (err1)
        {
            p_callback(new Error(`Can not find or create database dir: ${p_dbpath}`));
        }
        else
        {
            _repairMongoDB(p_dbpath, (err2) =>
            {
                if (err2)
                {
                    p_callback(new Error("Database is broken, can not auto-repair"));
                }
                else
                {
                    p_callback();
                }
            });
        }
    });
}

/**
 * 修复未正常关闭的数据库。
 */
function _repairMongoDB(p_dbpath, p_callback)
{
    fs.remove(path.resolve(p_dbpath, "mongod.lock"), p_callback);
}

@@ -353,25 +353,16 @@
 .start =
- function
  (p_call
@@ -362,24 +362,27 @@
 (p_callback)
+ =%3E
 %0A%7B%0A    const
@@ -951,25 +951,16 @@
 onnect =
- function
  (p_call
@@ -960,24 +960,27 @@
 (p_callback)
+ =%3E
 %0A%7B%0A    // TO
@@ -1005,96 +1005,8 @@
 ct.%0A
-    console.log(%60Connecting database: $%7Bprocess.env.MONGODB_CONNECTION %7C%7C config.db%7D%60);%0A
     
@@ -2148,19 +2148,13 @@
 d = 
-function ()
+() =%3E
 %0A%7B%0A 
@@ -2276,17 +2276,8 @@
 ns =
- function
  (p_
@@ -2281,24 +2281,27 @@
 (p_callback)
+ =%3E
 %0A%7B%0A    async

use arrow function