"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BrowserCallbackServer = void 0;
const http = require("http");
const url = require("url");
const open = require("open");
const logger = require("winston");
const path = require("path");
const fs = require("fs-extra");
const lodash = require("lodash");
const util_1 = require("util");
const WizError_1 = require("../WizError");
const SUCCESS_FILENAME = 'index.html';
const errorMessages = {
    title: 'The error occurred during your attempt to login to Ewizard CLI',
    message: 'Please, check the entered parameters and try again',
    info: 'You can close this window now.',
};
const RESOURCES_DIRECTORY = path.join(__dirname, '../../public/browser-callback-server');
const ignoredPaths = ['robots.txt', 'sitemap.xml'];
class BrowserCallbackServer {
    createCallbackUrl(port) {
        return 'http://localhost:' + port;
    }
    start(requestUrl, redirectPort, messages, onRequest, onError) {
        const server = http.createServer((req, res) => {
            const parsedUrl = url.parse('' + req.url, true);
            const pathName = parsedUrl.pathname || '';
            if (this.isPageLoaded(parsedUrl)) {
                res.end();
                server.close();
            }
            else {
                try {
                    onRequest(parsedUrl);
                    return this.respondForServer(server, req, res, 200, pathName, messages);
                }
                catch (error) {
                    onError(error);
                    return this.respondForServer(server, req, res, 400, pathName, errorMessages);
                }
            }
        });
        server.listen(redirectPort, () => {
            open(requestUrl);
        });
        server.on('connection', (socket) => {
            socket.unref();
        });
    }
    isPageLoaded(parsedUrl) {
        return parsedUrl.pathname === '/page-loaded';
    }
    respondForServer(server, req, res, statusCode, filename, messages) {
        return this.respondWithFile(req, res, 200, filename, messages)
            .catch((error) => {
            logger.error(error.message);
        });
    }
    respondWithFile(req, res, statusCode, filename, messages) {
        const fileFullPath = this.getFullPath(filename);
        const sendBody = (0, util_1.promisify)(res.end).bind(res);
        if (this.isIgnoredPath(filename)) {
            return sendBody();
        }
        return this.isDirectory(fileFullPath).then((isDirectory) => {
            const filePath = isDirectory ? this.getFullPath(SUCCESS_FILENAME) : fileFullPath;
            return fs.readFile(filePath)
                .then((response) => {
                let content = response;
                if (this.isHtmlFile(filePath)) {
                    content = this.setMessages(content.toString(), messages);
                }
                res.writeHead(statusCode, {
                    'Content-Length': content.length,
                });
                return sendBody(content);
            })
                .catch((error) => {
                throw new WizError_1.WizError('BROWSER_CALLBACK_FILE', filename, error.message);
            });
        });
    }
    isIgnoredPath(pathName) {
        return ignoredPaths.some(path => pathName.indexOf(path) > 0);
    }
    getFullPath(inputPath) {
        return path.join(RESOURCES_DIRECTORY, inputPath);
    }
    isHtmlFile(filePath) {
        return path.extname(filePath) === '.html';
    }
    setMessages(content, messages) {
        const resultContent = lodash.template(content)(messages);
        return Buffer.from(resultContent);
    }
    isDirectory(inputPath = '') {
        return fs.stat(inputPath).then((stat) => stat.isDirectory());
    }
}
exports.BrowserCallbackServer = BrowserCallbackServer;
//# sourceMappingURL=index.js.map