"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
/**
 * Defines and registers admin/management endpoints
 */
class MockController {
    /**
     *
     * @param {express.Application} app instance of express application
     * @param {string} mocksDir location of http mocks
     * @param {string} grpcMocksDir location of grpc mocks
     */
    constructor(app, mocksDir, grpcMocksDir) {
        /**
         * Registers management endpoints:
         * - GET /mocks - DEPRECATED
         * - DELETE /mocks - DEPRECATED
         * - GET /restart
         * - GET /ping
         * @returns {void}
         */
        this.register = () => {
            /**
             * Gets the list of available http and grpc mocks - deprecated
             */
            this.app.get("/mocks", (req, res) => {
                let results = walk(this.mocksDir);
                let grpcResults = walk(this.grpcMocksDir);
                results = results.map((result) => {
                    result = result.replace(this.mocksDir, "");
                    result = result.replace(".mock", "");
                    result = result.replace("__", "*");
                    let api = result.split("/");
                    let method = api.pop();
                    return { method: method, basePath: api.join("/") };
                });
                grpcResults = grpcResults.map((grpcResult) => {
                    grpcResult = grpcResult.replace(this.grpcMocksDir, "");
                    grpcResult = grpcResult.replace(".mock", "");
                    let [packageName, serviceName, methodName] = removeBlanks(grpcResult.split("/"));
                    console.log(removeBlanks(grpcResult.split("/")));
                    return { packageName: packageName, serviceName: serviceName, methodName: methodName };
                });
                let response = {
                    httpMocks: results,
                    grpcMocks: grpcResults,
                    metricsEndpoint: "/metrics",
                };
                res.send(response);
            });
            /**
             * Deletes a mock with it's path and http method - deprecated
             */
            this.app.delete("/mocks", (req, res) => {
                let mock = path_1.default.join(this.mocksDir, req.body.basePath.replace("*", "__"), req.body.method + ".mock");
                let status = "Mock Deleted Successfully";
                try {
                    fs_1.default.unlinkSync(path_1.default.resolve(mock));
                }
                catch (err) {
                    status = err;
                }
                res.send({ status: status, fileFound: fs_1.default.existsSync(mock) });
            });
            /**
             * Send message to master to kill all running workers and replace them with new workers
             * This is specifically for grpc services
             * In case a new protofile is added. server needs to be restarted to register new services
             */
            this.app.get("/restart", (req, res) => {
                setTimeout(() => {
                    process.send("restart");
                }, 1000);
                res.send({
                    message: "Restarting workers. Check /ping endpoint to validate if uptime and process id has refreshed.",
                    pid: process.pid,
                    currentProcessPptime: process.uptime(),
                });
            });
            /**
             * Get the status and uptime for a running process
             */
            this.app.get("/ping", (req, res) => {
                res.send({
                    message: "I am alive.",
                    pid: process.pid,
                    currentProcessUptime: process.uptime(),
                });
            });
        };
        this.app = app;
        this.mocksDir = mocksDir;
        this.grpcMocksDir = grpcMocksDir;
        this.register();
    }
}
exports.default = MockController;
/**
 * Recursively prepares a list of files in a given directory
 * @param dir mocksDir
 * @returns array of files in a given directory
 */
var walk = function (dir) {
    var results = [];
    var list = fs_1.default.readdirSync(dir);
    list.forEach(function (file) {
        file = dir + "/" + file;
        var stat = fs_1.default.statSync(file);
        if (stat && stat.isDirectory()) {
            /* Recurse into a subdirectory */
            results = results.concat(walk(file));
        }
        else {
            /* Is a file */
            results.push(file);
        }
    });
    return results;
};
const removeBlanks = (array) => {
    return array.filter(function (i) {
        return i;
    });
};
//# sourceMappingURL=CamouflageController.js.map