const fs = require('fs');
const { Router } = require('express');
const multipart = require('@connect/multipart');
const bunker = require('../middleware2/bunker');
const sendReqProp = require('../middleware2/sendReqProp');
const getBasicResponseHeaders = require('../lib2/getBasicResponseHeaders');
const getBody = require('../lib2/getBody');
const getEnv = require('../lib2/getEnv');
const getUrl = require('../lib2/getUrl');

const Api = {
    directory: require('../api2/directory'),
    dns: require('../api2/dns'),
    fouras: require('../api2/fouras'),
    gendarme: require('../api2/gendarme'),
    sender: require('../api2/sender'),
    setter: require('../api2/setter'),
    settings: require('../api2/settings'),
};

const UploadConfig = {
    maxFieldsSize: 104857600, // 100 MB
};

const PrivateEnvs = [
    'development',
    'ui-test',
    'testing',
];

let router = Router(); // eslint-disable-line new-cap

const apiList = Object.keys(Api).join('|');
const apiRoutes = [
    `/org/:orgId/:apiId(${apiList})/`, // @see DIR-9581
    `/:apiId(${apiList})/`,
];

router.use(apiRoutes, multipart(UploadConfig), (req, res, next) => {
    const body = getBody(req);
    const { _csrf, ...query } = req.query; // @see DIR-9810

    if (req.params.orgId && !req.ctx.orgId) {
        req.ctx.orgId = req.params.orgId;
    }

    // eslint-disable-next-line no-console
    console.log(`${req.method} ${req.baseUrl}${req.path}`, {
        request: {
            method: req.method,
            headers: req.headers,
            query,
            body,
        },
        requestUrl: getUrl(req),
        requestId: req.ctx.requestId,
        orgId: req.ctx.orgId,
        uid: req.blackbox && req.blackbox.uid,
    });

    let { path } = req;

    // часть клиентских приложений, запущенных до обновления апи-прокси, продолжают слать с клиента
    // в поллингах статуса сервисов запросы к organizations без префикса /v11, как того требует новая версия;
    // это приводит к многочисленным ошибкам 405 method_not_allowed в логах;
    // временно поддержим '/organizations/<org_id>/' без префикса /v11 (до конца июня 2020)
    if (req.params.apiId === 'directory' && /^\/organizations\/\d+\/$/.test(path)) {
        path = `/v11${path}`;

        // eslint-disable-next-line no-console
        console.log('Temp API proxy path patch', {
            requestId: req.ctx.requestId,
            originalPath: req.path,
            patchedPath: path,
        });
    }

    return Api[req.params.apiId](req)
        .send(req.method, path, {
            query,
            body,
        })
        .then(({ status, body, headers }) => {
            if (req.files) {
                Object.values(req.files)
                    .forEach(file => fs.existsSync(file.path) && fs.unlinkSync(file.path));
            }

            res.set(getBasicResponseHeaders(req));
            res.set('x-backend-duration', headers.get('x-duration'));

            return body.pipe(res.status(status));
        })
        .catch(() => {
            next();
        });
});

router.use('/bunker', bunker(), sendReqProp('bunker'));

if (PrivateEnvs.includes(getEnv())) {
    router.get('/blackbox', sendReqProp('blackbox'));
    router.get('/tvm', sendReqProp('tvm'));
}

module.exports = () => [
    require('../middleware2/tvm')(),
    require('../middleware2/blackbox')(),
    router,
];
