#!/bin/sh
"use strict";
':'; //; exec "$(command -v nodejs || command -v node)" "$0" "$@"
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const path_1 = __importDefault(require("path"));
const cors_1 = __importDefault(require("cors"));
const http_1 = __importDefault(require("http"));
require("dotenv/config");
const cli_1 = __importDefault(require("./routers/cli"));
const home_1 = __importDefault(require("./routers/home"));
const plugins_1 = __importDefault(require("./routers/plugins"));
const webSDK_1 = __importDefault(require("./routers/webSDK"));
const navigators_1 = __importDefault(require("./routers/navigators"));
const websocket_1 = require("./websocket");
const workspace_1 = require("./controllers/workspace");
const express_winston_1 = __importDefault(require("express-winston"));
const logger_1 = require("./utils/logger");
const models_1 = require("./models");
const database_1 = __importDefault(require("./database"));
const Sentry = __importStar(require("@sentry/node"));
const profiling_node_1 = require("@sentry/profiling-node");
// import cookieParser from 'cookie-parser';
// import {transports} from 'winston';
// import child_process from 'child_process';
// ['spawn', 'exec', 'fork', 'execFile'].forEach(method => {
//   // @ts-ignore
//   const original = child_process[method];
//   // @ts-ignore
//   child_process[method] = function(...args) {
//     logger.info("[LEAK TRACE] child_process.${method} called with:", args[0]);
//     console.trace('[LEAK TRACE] Stack for ${method}');
//     return original.apply(this, args)
//   }
// })
const isPostgresEnabled = process.env.ENABLE_POSTGRES == 'true';
const app = (0, express_1.default)();
if (process.env.ENABLE_SENTRY) {
    Sentry.init({
        dsn: process.env.SENTRY_DSN,
        integrations: [
            new Sentry.Integrations.Http({ tracing: true }),
            new Sentry.Integrations.Express({ app }),
            new profiling_node_1.ProfilingIntegration(),
        ],
        tracesSampleRate: 0.1,
        profilesSampleRate: 0.1,
    });
    // IMPORTANT: The requestHandler must be the first middleware on the app
    app.use(Sentry.Handlers.requestHandler());
    app.use(Sentry.Handlers.tracingHandler());
}
// app.use(cookieParser());
app.use(express_winston_1.default.logger({
    // transports: [new transports.Console()],
    winstonInstance: logger_1.logger,
    meta: true,
    msg: "{{req.method}} {{req.url}}",
    expressFormat: true,
    colorize: false,
    ignoreRoute: (req, res) => req.url.endsWith("healthcheck"),
}));
app.set('view engine', 'pug');
const server = http_1.default.createServer(app);
app.use((0, cors_1.default)());
// export const jsonParser = bodyParser.json({limit: '50mb'});
(0, websocket_1.createSocketServer)(server);
if (isPostgresEnabled) {
    database_1.default.connect();
    (0, models_1.dbInit)();
    database_1.default.sequelize.authenticate().catch((error) => {
        logger_1.logger.error('Unable to connect to the database:', error);
        if (process.env.ENABLE_SENTRY) {
            Sentry.captureException(error, {
                tags: {
                    location: 'database_connect',
                    error_type: 'connection_failure'
                }
            });
        }
        throw error;
    });
}
app.use(`/plugin-server/cli`, cli_1.default);
app.use(`/plugin-server/home`, home_1.default);
app.use(`/plugin-server/plugins`, plugins_1.default);
app.use(`/plugin-server/navigators`, navigators_1.default);
app.use(`/plugin-server/webSDK`, webSDK_1.default);
// const staticOptions = {
//   maxAge: '1000d', 
//   etag: true,   
//   lastModified: true, 
//   immutable: true 
// };
app.use('/plugin-server/public', express_1.default.static(path_1.default.resolve(__dirname, 'public'))); //, staticOptions));
// For handling spa
app.use('/plugin-server/public/ui/*', (req, res) => {
    res.sendFile(path_1.default.resolve(__dirname, 'public/ui/index.html'));
});
app.get('/plugin-server/healthcheck', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        if (isPostgresEnabled) {
            yield database_1.default.sequelize.authenticate();
        }
        res.send('ok');
    }
    catch (error) {
        logger_1.logger.error('Unable to connect to the database:', error);
        res.status(500).send('Database connection failed');
    }
}));
if (process.env.ENABLE_SENTRY) {
    app.use(Sentry.Handlers.errorHandler());
}
app.use((err, req, res, next) => {
    if (res.headersSent) {
        return next(err);
    }
    res.status(500);
    console.error("GLOBAL_ERROR", err);
    res.end();
});
(0, workspace_1.ensureDefaultWorkspace)().then(startupMessage => {
    server.listen(3100, '0.0.0.0', () => {
        logger_1.logger.log("info", `visit http://${process.env.NODE_ENV === "production"
            ? "cli.apptile.io"
            : "localhost:3100"}/plugin-server/cli/workspaces/list`);
        logger_1.logger.log("info", startupMessage);
    });
});
