/*
getAppFormsForApp(connections, options, cb)

connections: {
mongooseConnection: ...
}

options: {
uri:       db connection string,
userEmail: user email address string,
appId: the App Id
}


cb  - callback function (err)
327133
function getAppFormsForApp(connections, options, cb) {
  getAppFormsWithPopulatedForms(connections, options.restrictToUser, options.appId, function(err, forms) {
    if (err) {
      return cb(err);
    }
    return cb(undefined, {
      _id: options.appId,
      appId: options.appId,
      forms: forms
    });
  });
}
761819
function (appid) {
    return this.get('/appuserdetails', {
      // 'cc': this.options.country,
      // 'l': this.options.language,
      'v': 1,
      'appids': appid
    }).then(function (body) {
      console.log('appUserDetails - ', body)
      return Promise.resolve(body);
    });
  }
229599
function listDeployedForms(req, res, next) {
  var projectForms = req.appformsResultPayload.data || [];
  logger.debug("Middleware: listDeployedForms: ", {connection: req.connectionOptions, projectForms: projectForms});

  //Only Want The Project Ids
  projectForms = _.map(projectForms, function(form) {
    if (_.isObject(form)) {
      return form._id;
    } else {
      return form;
    }
  });

  forms.findForms(req.connectionOptions, projectForms, formsResultHandlers(constants.resultTypes.forms, req, next));
}
1243498
function (connectionName, collectionName, options, values, cb) {

      options = options || {};
      var connectionObject = connections[connectionName];
      var collection = connectionObject.collections[collectionName];

      // Update matching documents
      collection.update(options, values, function (err, results) {
        if (err) return cb(err);
        cb(null, results);
      });
    }
1296797
function (connectionName, collectionName, options, cb) {

      options = options || {};
      var connectionObject = connections[connectionName];
      var collection = connectionObject.collections[collectionName];

      // Find all matching documents
      collection.find(options, function (err, results) {
        if (err) return cb(err);
        cb(null, results);
      });
    }
29511
async function startApp(config = {}) {
  const {
    databaseURL = DEFAULT_MONGO,
    port = DEFAULT_PORT,
    host = DEFAULT_HOST,
    autoConnect = true
  } = config; // close all connections when running nodemon

  process.once('SIGUSR2', async () => {
    await app.destroy();
    process.kill(process.pid, 'SIGUSR2');
  });
  const db = new _database.default();
  const appMeta = await (0, _createApp.default)(config, db);
  const {
    app
  } = appMeta;
  const server = await listen(app, port, host);
  (0, _serverDestroy.default)(server);

  app.destroy = async () => {
    await Promise.all([disconnectFromDatabase(db), destroy(server)]);
  };

  const {
    port: serverPort
  } = server.address();
  const url = `http://localhost:${serverPort}`;
  const router = (0, _koaRouter.default)();

  const connect = async () => {
    await db.connect(databaseURL);
  };

  if (autoConnect) {
    await connect();
  }

  return { ...appMeta,
    router,
    url,
    ...(autoConnect ? {} : {
      connect
    })
  };
}
1050935
function populateAppProperties(props) {
    AppProperties.set("DB_NAME", props["db.name"]);
    AppProperties.set("DB_USER", props["db.user"]);
    AppProperties.set("DB_PASSWORD", props["db.password"]);
    AppProperties.set("DB_HOST", props["db.host"]);
    AppProperties.set("DB_PORT", props["db.port"]);

//    AppProperties.set("DB_URL", "mongodb://" + props['db.user'] + ":"
//        + props['db.password'] + "@" + props['db.host'] + ":" +
//        props['db.port'] + "/" + props['db.name']);

    AppProperties.set("SESSION_MAX_AGE", parseInt(props["session.max.age"]) * 60000);
    AppProperties.set("PASSWORD_ENC_ALGO", props["password.encryption.algorithm"]);
    AppProperties.set("IMAGE_HANDLER", props["image.handler"]);
    AppProperties.set("THUMB_DIMENSION", props["thumb.dimension"]);
    AppProperties.set("DEFAULT_THUMB_NAME", props["default.thumb.name"]);
    AppProperties.set("THUMB_BACKGROUND", props["thumb.background"]);
    AppProperties.set("IMAGE_DETAIL_DIMENSION", props["image.detail.dimension"]);
    AppProperties.set("PROD_STATIC_MAX_AGE", props["prod.static.max.age"]);
    AppProperties.set("DEV_STATIC_MAX_AGE", props["dev.static.max.age"]);
    AppProperties.set("AVAILABLE_LOCALES", props["available.locales"]);
    AppProperties.set("SCHEMA_LIST_MODEL_EVENTS", props["schema.list.model.events"]);
    AppProperties.set("SERVER_PORT", props["server.port"]);
    AppProperties.set("MAIL_KNOWN_SMTP", props["mail.known.smtp"]);
    AppProperties.set("MAIL_HOST", props["mail.host"]);
    AppProperties.set("MAIL_PORT", props["mail.port"]);
    AppProperties.set("MAIL_AUTH_USER", props["mail.auth.user"]);
    AppProperties.set("MAIL_AUTH_PASSWORD", props["mail.auth.password"]);
    AppProperties.set("STARTUP_MAIL_TEST", props["startup.mail.test"]);

    AppProperties.set("APP_STARTUP_ACTIONS_FILE", props["app.startup.actions.file"]);
    AppProperties.set("REQ_MIDDLEWARES", props["req.middlewares"]);

    //OAuth accounts login config
    var accounts = props["enabled.login.accounts"];
    accounts = accounts || AppProperties.get("ENABLED_LOGIN_ACCOUNTS");
    if (accounts) {
        AppProperties.set("ENABLED_LOGIN_ACCOUNTS", accounts);
        accounts = accounts.split(",");
        var accConfig = {};
        _.each(props, function (value, key) {
            var split = key.split(".");
            var acc = split[0];
            if (acc && _.contains(accounts, acc)) {
                accConfig[acc] = accConfig[acc] || {};
                //trying to convert string array into array
                try {
                    value = eval(value);
                }
                catch (e) {
                }
                accConfig[acc][split[1]] = value;
            }
        });

        AppProperties.set("LOGIN_ACCOUNTS_CONFIG", accConfig);
    }

    //cache configs
    AppProperties.set("GLOBAL_CACHE_STORE", props["global.cache.store"]);
    AppProperties.set("DEFAULT_CACHE_EXPIRE", eval(props["default.cache.expire"])); //evals the string to int
    AppProperties.set("DB_CACHE_STORE", props["db.cache.store"]);
    AppProperties.set("BOTTOM_SCRIPTS_CACHE_STORE", props["bottom.scripts.cache.store"]);
    AppProperties.set("TMPL_CACHE_STORE", props["tmpl.cache.store"]);
    AppProperties.set("CACHE_REDIS_HOST", props["cache.redis.host"]);
    AppProperties.set("CACHE_REDIS_PORT", props["cache.redis.port"]);

    props["show.plugin.view.permission.error"] &&
    AppProperties.set("SHOW_PLUGIN_VIEW_PERMISSION_ERR", JSON.parse(props["show.plugin.view.permission.error"]));

    //error templates
    AppProperties.set("APP_404_ERROR_TMPL", props["app.404.error.tmpl"]);
    AppProperties.set("APP_500_ERROR_TMPL", props["app.500.error.tmpl"]);
    AppProperties.set("APP_401_ERROR_TMPL", props["app.401.error.tmpl"]);
    AppProperties.set("PLUGIN_ERROR_TMPL", props["plugin.error.tmpl"]);

}
1276035
function getDatabase(callback) {
    node.log(`Getting database:\n${dbName}\n`);
    var dbdef = {id : dbName};
        return new Promise((resolve, reject) => {
            client.readDatabase(databaseUrl, (err, result) => {
                if (err) {
                    if (err.code == HttpStatusCodes.NOTFOUND) {
                        client.createDatabase(dbdef, (err, created) => {
                            if (err) reject(err)
                            else resolve(created);
                        });
                    } else {
                        reject(err);
                    }
                } else {
                    resolve(result);
                }
            });
        });
    }
294484
function findDataSources(connections, dataSources, cb) {
  //Just Want The Data Source IDs.
  logger.debug("findDataSources", {dataSources: dataSources});
  var dataSourceIDsToUpdate = _.map(dataSources, function(dataSourceUpdateData) {
    return dataSourceUpdateData.error ? null : dataSourceUpdateData._id;
  });

  dataSourceIDsToUpdate = _.compact(dataSourceIDsToUpdate);

  //No Valid Data Sources To Update. No Need To Search For Data Sources
  if (dataSourceIDsToUpdate.length === 0) {
    return cb(undefined, dataSourceIDsToUpdate);
  }

  var query = {

  };

  //Searching By ID. Just one mongo call to get them all. More Efficient
  query[CONSTANTS.DATA_SOURCE_ID] = {
    "$in": dataSourceIDsToUpdate
  };

  lookUpDataSources(connections, {
    query: query
  }, function(err, foundDataSources) {
    if (err) {
      logger.error("Error Finding Data Sources ", {error: err});
      return cb(buildErrorResponse({
        error: err,
        userDetail: "Unexpected Error When Searching For A Data Source",
        code: ERROR_CODES.FH_FORMS_UNEXPECTED_ERROR
      }));
    }

    //Map Found Data Source Documents
    var dsWithDocuments = _.map(dataSources, function(validDataSource) {
      var matchingDocument = _.find(foundDataSources, function(dataSourceDocument) {
        return _.isEqual(dataSourceDocument._id.toString(), validDataSource._id.toString());
      });

      //If the document is found, assign it to the object, if not, set an error
      if (matchingDocument) {
        validDataSource.document = matchingDocument;
      } else {
        validDataSource.error = buildErrorResponse({
          error: new Error("Data Source Not Found"),
          userDetail: "Data Source Not Found",
          code: ERROR_CODES.FH_FORMS_NOT_FOUND
        });
      }

      return validDataSource;
    });

    var validInvalidDataSources = updateValidAndInvalidDataSources(dsWithDocuments, []);

    logger.debug("findDataSources", {validInvalidDataSources: validInvalidDataSources});

    cb(undefined, validInvalidDataSources.valid, validInvalidDataSources.invalid);
  });
}
526673
function getAppContext(apps) {
  var funcs = [
    getAppContextFromArgv,
    getAppContextFromCwd,
    getAppContextFromCwdConfig
  ];
  return Promise.reduce(funcs, function(acc, func) {
    return acc || func(apps);
  }, null);
}
958344
function search(params, cb) {
  var resourcePath = config.addURIParams("/appforms/forms/search", params);
  var method = "POST";
  var data = params.searchParams;

  params.resourcePath = resourcePath;
  params.method = method;
  params.data = data;

  mbaasRequest.app(params, cb);
}
708990
function getAppsLists (callback) {
  return this.steam('getAppList').then(function (body) {
    var lists = Object.create(null);
    body.applist.apps.forEach(function (app) {
      var type = this.match(app.appid);
      if (!lists[type]) {
        lists[type] = [];
      }
      lists[type].push(app);
    }, this);
    return Promise.resolve(lists);
  }.bind(this)).nodeify(callback);
}
1239575
function connect(obj, cb) {
    if (obj.db) {
        return cb();
    }
    if (obj.pending) {
        return setImmediate(function () {
            connect(obj, cb);
        });
    }
    obj.pending = true;

    var url = constructMongoLink(obj.config.name, obj.config.prefix, obj.config.servers, obj.config.URLParam, obj.config.credentials);
    if (!url) {
        return cb(generateError(190));
    }

    mongoSkin.connect(url, obj.config.extraParam, function (err, db) {
        if (err) {
            obj.pending = false;
            return cb(err);
        } else {
            db.on('timeout', function () {
                console.log("Connection To Mongo has timed out!");
                obj.flushDb();
            });
            db.on('close', function () {
                console.log("Connection To Mongo has been closed!");
                obj.flushDb();
            });
            if (obj.db)
                obj.db.close();

            obj.db = db;
            obj.pending = false;
            return cb();
        }
    });

    /**
     *constructMongoLink: is a function that takes the below param and return the URL need to by mongoskin.connect
     *
     * @param dbName
     * @param prefix
     * @param servers
     * @param params
     * @param credentials
     * @returns {*}
     */
    function constructMongoLink(dbName, prefix, servers, params, credentials) {
        if (dbName && Array.isArray(servers)) {
            var url = "mongodb://";
            if (credentials && Object.hasOwnProperty.call(credentials, 'username') && credentials.hasOwnProperty.call(credentials, 'password')) {
                url = url.concat(credentials.username, ':', credentials.password, '@');
            }

            servers.forEach(function (element, index, array) {
                url = url.concat(element.host, ':', element.port, (index === array.length - 1 ? '' : ','));
            });

            url = url.concat('/');
            if (prefix) url = url.concat(prefix);
            url = url.concat(dbName);

            if (params && 'object' === typeof params && Object.keys(params).length) {
                url = url.concat('?');
                for (var i = 0; i < Object.keys(params).length; i++) {
                    url = url.concat(Object.keys(params)[i], '=', params[Object.keys(params)[i]], i === Object.keys(params).length - 1 ? '' : "&");
                }
            }
            return url;
        }
        return null;
    }
}
1133239
function getMongooseConnection(mongoDbUrl, logger, cb) {
  logger.debug("creating mongoose connection for data_source_update job", {mongoDbUrl: mongoDbUrl});
  var mongooseConnection = mongoose.createConnection(mongoDbUrl);
  return cb(undefined, mongooseConnection);
}
52233
function (collectionIdentity, criteria, cb) {
      return connectionObject.find(collectionIdentity, criteria, function(err, res){
        if (err) { return cb(err); }
        res.forEach(function(record){ utils.cleanOrientAttributes(record /*, TODO: add schema */); });
        cb(null, res);
      });
    }
1200621
async function getConnection(url, opts = {}) {
    try {
        const dbName = opts.databaseName;
        if (!dbName || dbName === '')
            throw boom.badImplementation('jollof-data-arangodb: databaseName config is required', { url, opts })

        const key = url + dbName;

        //Get connection
        let connection;
        if (connPool[key]) {
            connection = connPool[key];
        } else {
            connection = new Database(opts)
            connection.useBasicAuth(opts.username, opts.password)
            connPool[key] = connection;
        }

        //Now ensure database exists
        const dbNames = await connection.listDatabases();
        if (dbNames.indexOf(dbName) > -1) {
            //our db exists. use it.
            connection.useDatabase(dbName)
        } else {
            //our db does not exist. Attempting to create it
            await connection.createDatabase(dbName)
            connection.useDatabase(dbName)
        }

        return connection;
    } catch (e) {
        console.error(`There was an issue creating/ensuring connection to DB: ${url} with opts: ${util.inspect(opts)}`)
        throw new Error(e);
    }
}
304120
function list(appName, callback) {
    var url = format('/%s/apps/%s/config/', deis.version, appName);
    commons.get(url, function onListResponse(err, result) {
      callback(err, result ? result.tags : null);
    });
  }