"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importStar(require("fs"));
const path_1 = __importDefault(require("path"));
const path_resolver_1 = require("root/services/path-resolver");
const templates_1 = require("root/models/Endpoint/templates");
const Route_1 = __importDefault(require("root/models/Route"));
const models_1 = require("root/models");
var HttpMethod;
(function (HttpMethod) {
    HttpMethod["GET"] = "get";
    HttpMethod["POST"] = "post";
    HttpMethod["DELETE"] = "delete";
    HttpMethod["PUT"] = "put";
    HttpMethod["PATCH"] = "patch";
})(HttpMethod || (HttpMethod = {}));
exports.HttpMethod = HttpMethod;
class Endpoint {
    static get endpointsJsonPath() {
        return path_1.default.join(path_resolver_1.getPrjRoot(), 'endpoints.json');
    }
    static get functionsJsonPath() {
        return path_1.default.join(path_resolver_1.getPrjRoot(), 'functions.json');
    }
    static getList() {
        return __awaiter(this, void 0, void 0, function* () {
            const file = yield fs_1.promises.readFile(Endpoint.endpointsJsonPath);
            const endpoints = JSON.parse(file.toString());
            return endpoints.map(endpoint => {
                const ep = new Endpoint();
                ep.id = endpoint.id;
                ep.route = Route_1.default.parseFromText(endpoint.route);
                ep.method = endpoint.method;
                return ep;
            });
        });
    }
    static saveList(endpoints) {
        return __awaiter(this, void 0, void 0, function* () {
            const jsonEndpoints = endpoints.map(ep => {
                var _a, _b;
                return (Object.assign(Object.assign({}, ep), { route: ep.route.endpointRoute, authorizer: (_b = (_a = ep.authorizer) === null || _a === void 0 ? void 0 : _a.id, (_b !== null && _b !== void 0 ? _b : null)) }));
            });
            yield fs_1.promises.writeFile(Endpoint.endpointsJsonPath, JSON.stringify(jsonEndpoints, null, 2));
        });
    }
    create(route, method, authorizerId) {
        return __awaiter(this, void 0, void 0, function* () {
            this.route = route;
            this.method = method;
            const endpoints = yield Endpoint.getList();
            const authorizers = yield models_1.Authorizer.getList();
            if (authorizerId) {
                this.authorizer = authorizers.find(authorizer => authorizer.id === authorizerId);
            }
            else {
                this.authorizer = null;
            }
            this.id = (endpoints
                .map(endpoint => endpoint.id)
                .reduce((max, curr) => Math.max(max, curr), 0) || 0) + 1;
            endpoints.push(this);
            yield Endpoint.saveList(endpoints);
            if (!fs_1.default.existsSync(path_resolver_1.getEndpointsRoot())) {
                yield fs_1.promises.mkdir(path_resolver_1.getEndpointsRoot());
            }
            const routeVars = route.vars;
            const hasPayload = [HttpMethod.PATCH, HttpMethod.POST, HttpMethod.PUT].includes(this.method);
            const folderPath = path_1.default.join(path_resolver_1.getEndpointsRoot(), this.method + '-' + route.folderName);
            yield fs_1.promises.mkdir(folderPath);
            const functionName = this.method + route.functionName;
            yield fs_1.promises.writeFile(path_1.default.join(folderPath, 'index.ts'), templates_1.indexTemplate(hasPayload, routeVars, this.authorizer));
            yield fs_1.promises.writeFile(path_1.default.join(folderPath, 'index.test.ts'), templates_1.testTemplate(functionName, this.authorizer));
            yield fs_1.promises.writeFile(path_1.default.join(folderPath, 'handler.ts'), templates_1.handlerTemplate(hasPayload, routeVars, this.authorizer));
            yield fs_1.promises.writeFile(path_1.default.join(folderPath, 'interfaces.ts'), templates_1.interfacesTemplate(hasPayload, routeVars, this.authorizer));
            yield fs_1.promises.writeFile(path_1.default.join(folderPath, 'validations.ts'), templates_1.validationsTemplate(hasPayload, routeVars));
            yield fs_1.promises.writeFile(path_1.default.join(path_resolver_1.getSrcRoot(), 'exporter.ts'), templates_1.exporterTemplate(endpoints));
            const functions = yield Endpoint.getFunctions();
            let endpointFunction = {
                handler: `dist/exporter.${functionName}`,
                events: [
                    {
                        http: {
                            path: route.functionPath,
                            method: this.method,
                            cors: true,
                            authorizer: null,
                        },
                    },
                ],
            };
            if (this.authorizer) {
                endpointFunction.events[0].http.authorizer = this.authorizer.id;
                if (!functions[this.authorizer.id]) {
                    functions[this.authorizer.id] = {
                        handler: `dist/authorizers/${this.authorizer.id}.handler`,
                    };
                }
            }
            functions[functionName] = endpointFunction;
            /*
            functions[functionName] = {
              handler: `dist/exporter.${functionName}`,
              events: [
                {
                  http: {
                    path: route.functionPath,
                    method: this.method,
                    cors: true,
                  },
                },
              ],
            };
            */
            yield Endpoint.saveFunctions(functions);
        });
    }
    static getFunctions() {
        return __awaiter(this, void 0, void 0, function* () {
            const file = yield fs_1.promises.readFile(Endpoint.functionsJsonPath);
            return JSON.parse(file.toString()).functions;
        });
    }
    static saveFunctions(functions) {
        return __awaiter(this, void 0, void 0, function* () {
            yield fs_1.promises.writeFile(Endpoint.functionsJsonPath, JSON.stringify({ functions }, null, 2));
        });
    }
}
exports.default = Endpoint;
//# sourceMappingURL=index.js.map