import { App, IMiddleware, Middleware } from '@midwayjs/core';
import { NextFunction, Context, Application } from '@midwayjs/koa';
import { VOBase } from '../frame/VOBase';
import { get } from 'lodash';
import { ErrorVO } from '../frame/ErrorVO';
import { ServiceError } from '../error/service.error';
/**
 * 返回结果处理拦截器
 * 响应头的content-type含有'/files'的情况为请求文件,重写响应头即可
 * 正常请求都要通过视图处理基类(VOBase)格式化后返回
 */
@Middleware()
export class ResponseMiddleware implements IMiddleware<Context, NextFunction> {
  @App()
  app: Application;
  resolve() {
    return async (ctx: Context, next: NextFunction) => {
      await next();
      // 过滤掉 api文档的请求
      const swaggerPath = this.app.getConfig()?.swagger?.swaggerPath;
      const url = get(ctx, 'request.originalUrl');
      if (!url.includes(swaggerPath)) {
        //检查返回头,如果返回头中有/files,那就说明是读取文件.不能更改body
        const response = ctx.response;
        const resHeaderContentType = response.header['content-type'] as string;
        // 没有数据的情况,保证也可以返回
        if (!resHeaderContentType || !resHeaderContentType.includes('/files')) {
          const body = response.body;
          if (body instanceof ServiceError) {
            const r = new ErrorVO(body);
            return r;
          }
          const nb = new VOBase(body as object);
          return nb;
        } else {
          response.set('content-type', resHeaderContentType.replace('/files', ''));
        }
      }
    };
  }

  static getName(): string {
    return 'response';
  }
}
