const fs = require('fs')
const path = require('path')
const _cpro = require('child_process')

const com = require('@god/node-com')
const md5 = com.Tool.MD5

/**
 * 目录结构操作，删除查询
 * 0: delete, 删除；
 * 1: list, 查询；
 * 2: create, 创建；
 * 3: readfile, 文件；
 * 4: searchinfo, 直接根据姓名，搜索对应目录，并返回该目录下，info.txt文件中 所有内容
 * 5: searchlogvideo, 根据姓名，搜索参数(video目录+vid)所有该人员所有观看记录
 * 9: get-md5, 获取md5字符串, 鉴权使用；
 */
const dirOperate = (req, res) => {
  let operate = req.body.operate || ''
  let timestamp = Math.floor(new Date().getTime() / 100000000) + '00000000'
  let md5Str = md5('ezijing.com' + timestamp)
  if (operate === '9') { res.status(200).json({ 'timestamp': timestamp, 'MD5-auth': md5Str }); return }
  let auth = req.headers.auth || ''
  if (auth === md5Str) {
    _executeOperate(req, res)
  } else {
    res.status(200).json({ 'msg': '没有权限 访问该接口' })
  }
}

/**
 * 根据 对应参数，执行
 * @param {*} req 请求参数
 * @param {*} res 返回参数
 */
const _executeOperate = (req, res) => {
  let dir = req.body.dir || ''
  let operate = req.body.operate || ''
  let json = {}
  json.dirPath = dir
  json.arrJson = {}
  if (operate === '2') {
    _createDir(dir, (str) => {
      json.arrJson.msg = str
      res.status(200).json(json)
    })
    return
  }
  fs.stat(dir, (error, stats) => {
    if (error) {
      json.arrJson.msg = '当前目录，或文件不存在'
      /* 返回数据 */
      res.status(200).json(json)
    } else {
      if (operate === '0') { /* 删除 */
        _deleteDir(dir, stats, (str) => {
          json.arrJson.msg = str
          res.status(200).json(json)
        })
      } else if (operate === '1') { /* 查询 */
        _checkDir(dir, json, () => {
          res.status(200).json(json)
        })
      } else if (operate === '3') { /* 读取文件内容 */
        _readFile(dir, (data) => {
          res.status(200).send(data)
        })
      } else if (operate === '4') { /* 根据人名查询学生 基本信息 */
        let name = req.body.name
        _searchInfo(dir, name, (data) => {
          res.status(200).send(data)
        })
      } else if (operate === '5') { /* 搜索 视频记录行为 日志 */
        let name = req.body.name
        let opt = req.body.opt
        _searchLogVideo(dir, name, opt, (data) => {
          res.status(200).send(data)
        })
      } else {
        res.status(200).json({ 'msg': 'operate 参数错误' })
      }
    }
  })
}

/**
 * 参数 0（删除），执行方法
 * @param {string} dir 请求参数中，传过来的路径字符串
 * @param {object} stats 判断该路径，对应的属性状态
 * @param {function} callfunc 回调函数
 */
const _deleteDir = (dir, stats, callfunc) => {
  if (stats.isFile()) {
    fs.unlink(dir, () => {
      callfunc('文件删除成功')
    })
  } else if (stats.isDirectory()) {
    com.Tool.Directory.rmdir(dir, () => {
      callfunc('目录删除成功')
    })
  }
}
/**
 * 参数 1（查询），执行方法
 * @param {string} dir 请求参数中，传过来的路径字符串
 * @param {object} json 接口返回，整个json对象，传过来进行修改
 * @param {function} callfunc 回调函数
 */
const _checkDir = (dir, json, callfunc) => {
  let pa = fs.readdirSync(dir)
  let dirStr = 'dir'
  let dirCount = 0
  let fileStr = 'file'
  let fileCount = 0
  for (let j = 0; j < pa.length; j++) {
    let elem = pa[j]
    let stat = fs.statSync(path.resolve(dir, elem))
    if (stat.isFile()) {
      json.arrJson[fileStr + (fileCount++)] = elem
    }
    if (stat.isDirectory()) {
      json.arrJson[dirStr + (dirCount++)] = elem
    }
  }
  /* 统计总个数 */
  json.count = pa.length
  callfunc()
}
/**
 * 参数 2（创建），执行方法
 * @param {string} dir 请求参数中，传过来的路径字符串
 * @param {function} callfunc 回调函数
 */
const _createDir = (dir, callfunc) => {
  com.Tool.Directory.mkdir(dir, () => {
    callfunc('目录创建成功')
  })
}
/**
 * 参数 3（读文件），执行方法
 * @param {string} dir 请求参数中，传过来的路径字符串，必须是文件，否则出错
 * @param {function} callfunc 回调函数
 */
const _readFile = (dir, callfunc) => {
  callfunc(fs.readFileSync(dir))
}
/**
 * 参数 4（搜索），执行方法
 * @param {string} dir 请求参数中，传过来的路径字符串，必须是文件，否则出错
 * @param {string} name 请求参数中，增加一个name字段，用这个字段匹配相关目录
 * @param {function} callfunc 回调函数
 */
const _searchInfo = (dir, name, callfunc) => {
  let pa = fs.readdirSync(dir)
  let reg = new RegExp(name, 'gi')
  let _path = ''
  for (let j = 0; j < pa.length; j++) {
    let elem = pa[j]
    if (reg.test(elem)) {
      _path = path.resolve(dir, elem)
      break
    }
  }
  if (_path) {
    callfunc(fs.readFileSync(path.resolve(_path, 'info.txt')))
  } else {
    callfunc('没有该学生或文件解析出错')
  }
}
/**
 * 参数 5（视频学习行为查询），执行方法
 * @param {string} dir 请求参数中，传过来的路径字符串，必须是文件，否则出错
 * @param {string} name 请求参数中，增加一个name字段，用这个字段匹配相关目录
 * @param {string} opt 请求参数中，逗号隔开，第一个为 video: 视频行为记录信息；第二个为 vid: 视频id
 * @param {function} callfunc 回调函数
 */
const _searchLogVideo = (dir, name, opt, callfunc) => {
  let pa = fs.readdirSync(dir)
  let reg = new RegExp(name, 'gi')
  let _path = ''
  for (let j = 0; j < pa.length; j++) {
    let elem = pa[j]
    if (reg.test(elem)) {
      _path = path.resolve(dir, elem)
      break
    }
  }
  if (!_path) {
    callfunc('没有该学生或文件解析出错')
  } else {
    let _arr = opt.split(',')
    let _videoPath = path.resolve(_path, _arr[0])
    /* 对路径进行处理，保证shell可识别 */
    _videoPath = _videoPath.replace(/ /gi, '\\ ')
    let _catStr = 'cat *.log'
    let _grepStr = "grep '" + _arr[1] + "'"
    let _sortStr = 'sort -t ' + String.fromCharCode(0x001) + ' -k1,2nr'
    let _grepOptStr = _arr[2] ? (" | grep -o '" + [_arr[1] + '', '[0-9]\\+', '[0-9]\\+', '[0-9]\\+'].join(String.fromCharCode(0x001)) + "'") : ''
    _cpro.exec('cd ' + _videoPath + ' && ' + _catStr + ' | ' + _grepStr + ' | ' + _sortStr + _grepOptStr, (err, stdout, stderr) => {
      if (err) {
        console.log(err)
        callfunc(err)
        return
      }
      if (stdout) {
        callfunc(stdout)
      } else {
        callfunc('查无此项，请检查vid或其他参数')
      }
    })
    /* 再增加一个 日志查询 记录 执行时间等 */
  }
}

module.exports = {
  dirOperate: dirOperate
}
