<commit_before>import * as fs from 'fs';
import * as path from 'path';
import * as http from 'http';
import * as express from 'express';
import * as socket from 'socket.io';
import {Module} from '../modules/Module';
import {IRouter, IRouting, IRouterConfiguration} from './Routing';
import {ConfigProvider, ModuleProvider, RouteProvider, RouterProvider, SocketProvider, ViewProvider} from './Utils';

export abstract class Kernel {
    protected port: number;
    protected hasSocket: boolean = false;
    protected io: SocketIO.Server = null;
    protected app: express.Express = null;
    protected server: http.Server = null;
    protected viewEngine: string = 'pug';

    protected abstract registerModules(): Module[];
    protected abstract dirname(): string;

    public constructor() {
        let moduleProvider = ModuleProvider.getInstance();
        let configProvider = ConfigProvider.getInstance();
        let routerProvider = RouterProvider.getInstance();

        moduleProvider.setModules(this.registerModules());
        routerProvider.getAppRouters(this.dirname());
        configProvider.getAppConfig(this.dirname());
    }

    /**
     * Execute will parse args and run command
     */
    public execute() {}

    public enableSocket() {
        this.hasSocket = true;
    }

    public setViewsEngine(engine: string) {
        this.viewEngine = engine;
    }

    /**
     * Listen will run an express server
     */
    public listen(port: number) {
        let routeProvider = RouteProvider.getInstance();

        this.port = port;
        this.app = express();
        this.server = http.createServer(this.app);
        this.addSettings();
        this.app.use(routeProvider.applyPublicRoutes());
        this.app.use(routeProvider.applyRoutes());
        this.createSockets();
        // TODO: add error fallback
        this.server.listen(port);
    }

    public destroy() {
        this.close();
        (ConfigProvider.getInstance() as any)._instance = null;
        (ModuleProvider.getInstance() as any)._instance = null;
        (RouterProvider.getInstance() as any)._instance = null;
        (RouteProvider.getInstance() as any)._instance = null;
        (ViewProvider.getInstance() as any)._instance = null;
    }

    public close() {
        if (this.server !== null) {
            this.server.close();
            this.server = null;
        }
    }

    protected addSettings(): void {
        let viewProvider = ViewProvider.getInstance();

        this.app.set('view engine', this.viewEngine);
        this.app.set('views', viewProvider.getViewDirectories());
        this.app.set('port', this.port);
    }

    protected createSockets() {
        if (this.hasSocket) {
            let socketProvider = SocketProvider.getInstance();

            this.io = socketProvider.applySockets(this.server);
        }
    }
}<commit_msg>Kernel app/server creation is able to override<commit_after>import * as fs from 'fs';
import * as path from 'path';
import * as http from 'http';
import * as express from 'express';
import * as socket from 'socket.io';
import {Module} from '../modules/Module';
import {IRouter, IRouting, IRouterConfiguration} from './Routing';
import {ConfigProvider, ModuleProvider, RouteProvider, RouterProvider, SocketProvider, ViewProvider} from './Utils';

export abstract class Kernel {
    protected port: number;
    protected hasSocket: boolean = false;
    protected io: SocketIO.Server = null;
    protected app: express.Express = null;
    protected server: http.Server = null;
    protected viewEngine: string = 'pug';

    protected abstract registerModules(): Module[];
    protected abstract dirname(): string;

    public constructor() {
        let moduleProvider = ModuleProvider.getInstance();
        let configProvider = ConfigProvider.getInstance();
        let routerProvider = RouterProvider.getInstance();

        moduleProvider.setModules(this.registerModules());
        routerProvider.getAppRouters(this.dirname());
        configProvider.getAppConfig(this.dirname());
    }

    /**
     * Execute will parse args and run command
     */
    public execute() {}

    public enableSocket() {
        this.hasSocket = true;
    }

    public setViewsEngine(engine: string) {
        this.viewEngine = engine;
    }

    /**
     * Listen will run an express server
     */
    public listen(port: number) {
        this.port = port;
        this.createApp();
        this.createServer();
        this.addSettings();
        this.applyRoutes();
        this.createSockets();
        // TODO: add error fallback
        this.server.listen(port);
    }

    public destroy() {
        this.close();
        (ConfigProvider.getInstance() as any)._instance = null;
        (ModuleProvider.getInstance() as any)._instance = null;
        (RouterProvider.getInstance() as any)._instance = null;
        (RouteProvider.getInstance() as any)._instance = null;
        (ViewProvider.getInstance() as any)._instance = null;
    }

    public close() {
        if (this.server !== null) {
            this.server.close();
            this.server = null;
        }
    }

    /**
     * Can be override
     * this.app.use(...)
     */
    protected createApp() {
        this.app = express();
    }

    protected createServer() {
        this.server = http.createServer(this.app);
    }

    protected addSettings(): void {
        let viewProvider = ViewProvider.getInstance();

        this.app.set('view engine', this.viewEngine);
        this.app.set('views', viewProvider.getViewDirectories());
        this.app.set('port', this.port);
    }

    protected applyRoutes() {
        let routeProvider = RouteProvider.getInstance();

        this.app.use(routeProvider.applyPublicRoutes());
        this.app.use(routeProvider.applyRoutes());
    }

    protected createSockets() {
        if (this.hasSocket) {
            let socketProvider = SocketProvider.getInstance();

            this.io = socketProvider.applySockets(this.server);
        }
    }
}
{'fraction_non_alphanumeric': 0.12056384742951907, 'fraction_numerical': 0.0, 'mean_word_length': 2.648517846339988, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '719853', 'n_tokens_mistral': 1601, 'n_tokens_neox': 1578, 'n_words': 401}