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

function getHeaders(req) {
    const { tvm_tickets: tvmTickets, headers } = req.context;

    return Object.assign({}, headers, {
        'X-Ya-Service-Ticket': tvmTickets.dns,
    });
}

function enableDomain(req, res, next) {
    const { domain } = req.query;

    return sendHandledRequest({
        method: 'post',
        url: `${req.config.api.dns}/domains/`,
        headers: getHeaders(req),
        body: {
            name: `${domain}.`,
        },
        source: req,
        label: 'dns.enable_domain',
    })
        .then(data => next ? next() : data)
        .catch(next);
}

function getDomain(req, res, next) {
    const { domain } = req.query;

    return sendHandledRequest({
        method: 'get',
        url: `${req.config.api.dns}/domains/${encodeURIComponent(domain)}./`,
        headers: getHeaders(req),
        source: req,
        label: 'dns.get_domain',
    })
        .then(data => next ? next() : data)
        .catch(next);
}

function getRecords(req, res, next) {
    const { domain } = req.query;

    const prepare = new Promise(resolve => {
        getDomain(req, res)
            .then(resolve)
            // если домена нет в днс-хостинге, пытаемся включить его;
            // это опционально, поэтому промис prepare резолвим при любом исходе;
            // если домен не удастся включить, запрос к records всё равно
            // даст актуальную картину
            .catch(() => {
                enableDomain(req, res)
                    .then(resolve)
                    .catch(resolve);
            });
    });

    return prepare
        .then(() => sendHandledRequest({
            method: 'get',
            url: `${req.config.api.dns}/domains/${encodeURIComponent(domain)}./records/`,
            query: {
                offset: 0,
                // TODO: chunks + infinite scroll
                size: 5000,
            },
            headers: getHeaders(req),
            source: req,
            label: 'dns.get_records',
        }))
        .then(data => {
            req.context.dns_records = _.keyBy(_.get(data, 'items', []), 'id');

            return next ? next() : data;
        })
        .catch(() => {
            req.context.dns_records = {};

            return next ? next() : {};
        });
}

// передана запись с id - будет обновлена;
// передана запись без id - будет создана новая
function submitRecord(req, res, next) {
    const { domain } = req.query;

    return sendHandledRequest({
        method: 'post',
        url: `${req.config.api.dns}/domains/${encodeURIComponent(domain)}./records/`,
        headers: getHeaders(req),
        source: req,
        label: 'dns.update_record',
    })
        .then(data => {
            req.context.dns_records = {
                [data.id]: data,
            };

            return next ? next() : data;
        })
        .catch(next);
}

function removeRecord(req, res, next) {
    const { domain, id } = req.query;

    return sendHandledRequest({
        method: 'delete',
        url: `${req.config.api.dns}/domains/${encodeURIComponent(domain)}./records/${encodeURIComponent(id)}/`,
        headers: getHeaders(req),
        source: req,
        label: 'dns.remove_record',
    })
        .then(() => next())
        .catch(next);
}

module.exports = {
    getRecords,
    submitRecord,
    removeRecord,
};
