'use strict';

const fs = require('fs');
const path = require('path');
const utils = require('./utils')
const routes = require('./routes');
const redisConnect = require('./service/redis')
const socketConect = require('./service/socket')
const mqttVideoServer = require('./service/mqttVideoServer')
const paasRequest = require('./service/paasRequest');
const authenticator = require('./middlewares/authenticator');
const schedule = require('./schedule')
// const apiLog = require('./middlewares/api-log');

module.exports.entry = function (app, router, opts) {
   app.fs.logger.log('info', '[FS-AUTH]', 'Inject auth and api mv into router.');

   app.fs.api = app.fs.api || {};
   app.fs.utils = app.fs.utils || {};
   app.fs.api.authAttr = app.fs.api.authAttr || {};
   app.fs.api.logAttr = app.fs.api.logAttr || {};

   // 顺序固定 ↓ 
   redisConnect(app, opts)
   socketConect(app, opts)
   mqttVideoServer(app, opts)

   // 实例其他平台请求方法
   paasRequest(app, opts)

   // 工具类函数
   utils(app, opts)

   // 定时任务
   schedule(app, opts)

   // 鉴权中间件
   router.use(authenticator(app, opts));

   // 日志记录
   // router.use(apiLog(app, opts));

   router = routes(app, router, opts);
};

module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Sequelize, models: {} }
   // 加载定义模型 历史写法
   // require('./models/nvr')(dc);

   // 模型关系摘出来 初始化之后再定义关系才行
   fs.readdirSync(path.join(__dirname, '/models')).forEach((filename) => {
      require(`./models/${filename}`)(dc)
   });

   const {
      Nvr, Camera, CameraAbility, CameraAbilityBind, CameraKind, CameraRemark,
      GbCamera, SecretYingshi, Vender, CameraStatus, CameraStatusResolve, CameraStatusLog,
      CameraStatusPushConfig, CameraStatusPushMonitor, CameraStatusPushLog, CameraStatusPushReceiver, CameraStatusOfflineLog,
      Mirror, MirrorTree, MirrorFilterGroup, MirrorFilter, MirrorCamera
   } = dc.models;

   // Nvr.belongsTo(User, { foreignKey: 'userId', targetKey: 'id' });
   // User.hasMany(Nvr, { foreignKey: 'userId', sourceKey: 'id' });

   Camera.belongsToMany(CameraAbility, { through: CameraAbilityBind, foreignKey: 'cameraId', otherKey: 'abilityId' });

   CameraRemark.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
   Camera.hasMany(CameraRemark, { foreignKey: 'cameraId', sourceKey: 'id' });

   Camera.belongsTo(CameraKind, { foreignKey: 'kindId', targetKey: 'id' });
   CameraKind.hasMany(Camera, { foreignKey: 'kindId', sourceKey: 'id' });

   Camera.belongsTo(Nvr, { foreignKey: 'nvrId', targetKey: 'id' });
   Nvr.hasMany(Camera, { foreignKey: 'nvrId', sourceKey: 'id' });

   Nvr.belongsTo(GbCamera, { foreignKey: 'serialNo', targetKey: 'streamid', as: 'gbNvr' });
   GbCamera.hasMany(Nvr, { foreignKey: 'serialNo', sourceKey: 'streamid', as: 'gbNvr' });

   Camera.belongsTo(GbCamera, { foreignKey: 'gbId', targetKey: 'id' });
   GbCamera.hasMany(Camera, { foreignKey: 'gbId', sourceKey: 'id' });

   Camera.belongsTo(SecretYingshi, { foreignKey: 'yingshiSecretId', targetKey: 'id' });
   SecretYingshi.hasMany(Camera, { foreignKey: 'yingshiSecretId', sourceKey: 'id' });

   Camera.belongsTo(Vender, { foreignKey: 'venderId', targetKey: 'id' });
   Vender.hasMany(Camera, { foreignKey: 'venderId', sourceKey: 'id' });

   Nvr.belongsTo(Vender, { foreignKey: 'venderId', targetKey: 'id' });
   Vender.hasMany(Nvr, { foreignKey: 'venderId', sourceKey: 'id' });

   CameraStatusResolve.belongsTo(CameraStatus, { foreignKey: 'statusId', targetKey: 'id' });
   CameraStatus.hasMany(CameraStatusResolve, { foreignKey: 'statusId', sourceKey: 'id' });

   CameraStatusLog.belongsTo(CameraStatus, { foreignKey: 'statusId', targetKey: 'id' });
   CameraStatus.hasMany(CameraStatusLog, { foreignKey: 'statusId', sourceKey: 'id' });

   CameraStatusPushMonitor.belongsTo(CameraStatusPushConfig, { foreignKey: 'configId', targetKey: 'id' });
   CameraStatusPushConfig.hasMany(CameraStatusPushMonitor, { foreignKey: 'configId', sourceKey: 'id' });

   CameraStatusPushMonitor.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
   Camera.hasMany(CameraStatusPushMonitor, { foreignKey: 'cameraId', sourceKey: 'id' });

   CameraStatusPushLog.belongsTo(CameraStatusPushConfig, { foreignKey: 'pushConfigId', targetKey: 'id' });
   CameraStatusPushConfig.hasMany(CameraStatusPushLog, { foreignKey: 'pushConfigId', sourceKey: 'id' });

   CameraStatusPushReceiver.belongsTo(CameraStatusPushConfig, { foreignKey: 'configId', targetKey: 'id' });
   CameraStatusPushConfig.hasMany(CameraStatusPushReceiver, { foreignKey: 'configId', sourceKey: 'id' });

   CameraStatusOfflineLog.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
   Camera.hasMany(CameraStatusOfflineLog, { foreignKey: 'cameraId', sourceKey: 'id' });

   MirrorTree.belongsTo(Mirror, { foreignKey: 'mirrorId', targetKey: 'id' });
   Mirror.hasMany(MirrorTree, { foreignKey: 'mirrorId', sourceKey: 'id' });

   MirrorFilterGroup.belongsTo(Mirror, { foreignKey: 'mirrorId', targetKey: 'id' });
   Mirror.hasMany(MirrorFilterGroup, { foreignKey: 'mirrorId', sourceKey: 'id' });

   MirrorFilter.belongsTo(MirrorFilterGroup, { foreignKey: 'groupId', targetKey: 'id' });
   MirrorFilterGroup.hasMany(MirrorFilter, { foreignKey: 'groupId', sourceKey: 'id' });

   MirrorCamera.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
   Camera.hasMany(MirrorCamera, { foreignKey: 'cameraId', sourceKey: 'id' });

   MirrorCamera.belongsTo(Mirror, { foreignKey: 'mirrorId', targetKey: 'id' });
   Mirror.hasMany(MirrorCamera, { foreignKey: 'mirrorId', sourceKey: 'id' });
};