const requestMap = new Map();

const mergeRequestMap = new Map();
const requestQueue = new Map();

function handleCachingStart(ctx) {
    const isRequesting = mergeRequestMap.get(ctx.key);
    if (isRequesting) {
        return new Promise((resolve) => {
            const queue = requestQueue.get(ctx.key) || [];
            requestQueue.set(ctx.key, queue.concat(resolve));
        });
    }
    mergeRequestMap.set(ctx.key, true);
}

function handleRepeatRequest(ctx) {
    const queue = requestQueue.get(ctx.key);
    if (queue && queue.length > 0) {
        queue.forEach((resolve) => {
            if (ctx.error) {
                resolve({
                    error: ctx.error
                });
            } else {
                resolve({
                    response: ctx.response
                });
            }
        });
    }
    requestQueue.delete(ctx.key);
    mergeRequestMap.delete(ctx.key);
}

export default async (ctx, next) => {
    if (ctx.config.mergeRequest) {
        const result = await handleCachingStart(ctx);
        if (result) {
            Object.keys(result).forEach((key) => {
                ctx[key] = result[key];
            });
            return;
        }
    } else {
        if (requestMap.get(ctx.key) && !ctx.config.mergeRequest) {
            ctx.error = {
                type: 'REPEAT',
                msg: '重复请求',
                config: ctx.config
            };
            return;
        }
        requestMap.set(ctx.key, true);
    }

    await next();

    if (ctx.config.mergeRequest) {
        handleRepeatRequest(ctx);
    } else {
        requestMap.delete(ctx.key);
    }
};
