/**
 * 操作审计日志中间件
 *
 * 记录每次 API 操作到日志文件（谁、什么时间、做了什么）
 * 版权：国作登字-2026-A-00037559
 */

'use strict';

var fs = require('fs');
var path = require('path');

// 优先使用配置的目录，本地开发时回退到项目内目录
var AUDIT_LOG_DIR = process.env.AUDIT_LOG_DIR ||
  path.join(__dirname, '../../logs/audit');

/**
 * 审计日志中间件
 * 拦截请求和响应，记录操作信息
 */
function auditLog(req, res, next) {
  var startTime = Date.now();

  var logEntry = {
    timestamp: new Date().toISOString(),
    devId: (req.user && req.user.devId) || req.headers['x-dev-id'] || 'anonymous',
    method: req.method,
    path: req.path,
    ip: req.ip
  };

  // 对 POST/PATCH 请求记录请求体（排除敏感字段）
  if ((req.method === 'POST' || req.method === 'PATCH') && req.body) {
    var sanitizedBody = Object.assign({}, req.body);
    delete sanitizedBody.password;
    delete sanitizedBody.token;
    delete sanitizedBody.confirmToken;
    logEntry.body = sanitizedBody;
  }

  // 拦截响应完成
  var originalSend = res.send;
  res.send = function(body) {
    logEntry.responseTime = Date.now() - startTime;
    logEntry.statusCode = res.statusCode;

    // 异步写入日志，不阻塞响应
    fs.mkdir(AUDIT_LOG_DIR, { recursive: true }, function(mkdirErr) {
      if (mkdirErr) {
        console.error('审计日志目录创建失败:', mkdirErr.message);
        return;
      }
      var today = new Date().toISOString().split('T')[0];
      var logFile = path.join(AUDIT_LOG_DIR, 'audit-' + today + '.jsonl');
      fs.appendFile(logFile, JSON.stringify(logEntry) + '\n', function(writeErr) {
        if (writeErr) console.error('审计日志写入失败:', writeErr.message);
      });
    });

    return originalSend.call(this, body);
  };

  next();
}

module.exports = { auditLog: auditLog };
