const _ = require('lodash');
const sendHandledRequest = require('../lib/sendHandledRequest');
const logger = require('../lib/logger');
const config = require('../config');

function fetchTicket(req, client, destination, headers) {
    const requestOptions = {
        method: 'get',
        url: `${config.api.tvm}/tickets?src=${client.self_tvm_id}&dsts=${destination.dst_id}`,
        headers,
        source: req,
        noTrailingSlash: true,
    };

    return sendHandledRequest(requestOptions)
        .then(data => {
            logger.info(`[TVM] Fetched ${client.self_tvm_id}-to-${destination.dst_id} ticket`, req);

            return _.get(data, [destination.key, 'ticket']);
        })
        .catch(error => {
            logger.error(`[TVM] Failed to fetch ${client.self_tvm_id}-to-${destination.dst_id} ticket`, req, error);

            return null;
        });
}

function fetchAllTickets(req, res, next) {
    const token = process.env.QLOUD_TVM_TOKEN;

    if (!token) {
        req.context.auth = {
            errorCode: 401,
            message: 'Missing QLOUD_TVM_TOKEN',
        };

        return next();
    }

    const tvmConfig = JSON.parse(process.env.QLOUD_TVM_CONFIG);
    const clients = tvmConfig ? tvmConfig.clients : null;

    if (!clients) {
        req.context.auth = {
            errorCode: 401,
            message: 'Invalid QLOUD_TVM_CONFIG',
        };

        return next();
    }

    const headers = {
        Authorization: token,
        'x-request-id': _.get(req.context, 'headers.x-request-id'),
    };

    const requests = [];
    const cache = {};

    Object.keys(clients).forEach(clientKey => {
        const client = Object.assign({ key: clientKey }, clients[clientKey]);
        const destinations = client.dsts;

        Object.keys(destinations).forEach(destinationKey => {
            const keyPath = ['tvm_tickets', _.snakeCase(destinationKey)];
            const destination = Object.assign({ key: destinationKey }, destinations[destinationKey]);

            const ticketId = `${client.self_tvm_id}-${destination.dst_id}`;

            requests.push(
                // чтобы не дублировать запросы для сервисов, работающих под одним tvm id
                // (таких как gendarme, fouras, setter)
                (cache[ticketId] || (cache[ticketId] = fetchTicket(req, client, destination, headers)))
                    .then(ticket => {
                        logger.info(`[TVM] Received '${destinationKey}' ticket`, req);

                        return _.set(req.context, keyPath, ticket);
                    })
            );
        });
    });

    return Promise.all(requests)
        .then(() => next())
        .catch(() => next());
}

module.exports = fetchAllTickets;
