"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(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 cookie_1 = __importDefault(require("cookie"));
const http_1 = __importDefault(require("http"));
const koa_1 = __importDefault(require("koa"));
const koa_bodyparser_1 = __importDefault(require("koa-bodyparser"));
const koa_mount_1 = __importDefault(require("koa-mount"));
const koa_qs_1 = __importDefault(require("koa-qs"));
const koa_static_1 = __importDefault(require("koa-static"));
const path_1 = __importDefault(require("path"));
const socket_io_1 = __importDefault(require("socket.io"));
const typedi_1 = require("typedi");
const plugin_manager_1 = __importDefault(require("../plugin-manager"));
const services_1 = require("../services");
const router_1 = __importDefault(require("./router"));
let Manager = class Manager {
    constructor() {
        this.httpTrafficService = typedi_1.Container.get(services_1.HttpTrafficService);
        this.configureService = typedi_1.Container.get(services_1.ConfigureService);
        this.profileService = typedi_1.Container.get(services_1.ProfileService);
        this.hostService = typedi_1.Container.get(services_1.HostService);
        this.mockDataService = typedi_1.Container.get(services_1.MockDataService);
        this.ruleService = typedi_1.Container.get(services_1.RuleService);
        this.pluginManager = typedi_1.Container.get(plugin_manager_1.default);
        // 初始化koa
        this.app = new koa_1.default();
        // query string
        koa_qs_1.default(this.app);
        // body解析
        this.app.use(koa_bodyparser_1.default({
            formLimt: '5mb',
            jsonLimit: '5mb',
            textLimit: '5mb',
        }));
        // 路由
        this.app.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
            // 取用户Id
            const cookies = cookie_1.default.parse(ctx.request.headers.cookie || '');
            ctx.userId = cookies.userId || 'root';
            yield next();
        }));
        this.app.use(router_1.default());
        // 静态资源服务
        this.app.use(koa_static_1.default(path_1.default.join(__dirname, '../../../site')));
        this.app.use(koa_mount_1.default('/plugins', this.pluginManager.getUIApp()));
        // 创建server
        this.server = http_1.default.createServer(this.app.callback());
        // socketio
        this.io = new socket_io_1.default(this.server);
        // 初始化socket io
        this._initTraffic();
        this._initManger();
    }
    listen(port) {
        // 启动server
        this.server.listen(port);
    }
    // http流量监控界面
    _initTraffic() {
        const socket = this.io.of('/httptrafic');
        // 客户端发起连接请求
        socket.on('connection', client => {
            const userId = this._getUserId(client);
            client.join(userId);
            this.httpTrafficService.incMonitor(userId);
            // 推送过滤器，状态
            const state = this.httpTrafficService.getStatus(userId);
            client.emit('state', state);
            const filter = this.httpTrafficService.getFilter(userId);
            client.emit('filter', filter);
            client.emit('clear');
            client.on('disconnect', () => {
                this.httpTrafficService.decMonitor(userId);
            });
        });
        // 监听logRespository事件
        this.httpTrafficService.on('traffic', (userId, rows) => {
            socket.to(userId).emit('rows', rows);
        });
        // 过滤器改变
        this.httpTrafficService.on('filter', (userId, filter) => {
            socket.to(userId).emit('filter', filter);
        });
        // 状态改变
        this.httpTrafficService.on('state-change', (userId, state) => {
            socket.to(userId).emit('state', state);
        });
        // 清空
        this.httpTrafficService.on('clear', userId => {
            socket.to(userId).emit('clear');
            const state = this.httpTrafficService.getStatus(userId);
            socket.to(userId).emit('state', state);
        });
    }
    // 管理界面 使用的功能
    _initManger() {
        const socket = this.io.of('/manager');
        // 注册通知
        socket.on('connection', (client) => __awaiter(this, void 0, void 0, function* () {
            // 监听内部状态的客户端,这些客户端获取当前生效的host、rule
            const userId = this._getUserId(client);
            client.join(userId);
            // 推送最新数据
            // proxy配置
            const config = yield this.configureService.getConfigure();
            client.emit('configure', config);
            // 个人配置
            const profile = yield this.profileService.getProfile(userId);
            client.emit('profile', profile);
            const mappedClientIps = yield this.profileService.getClientIpsMappedToUserId(userId);
            client.emit('mappedClientIps', mappedClientIps);
            // host文件列表
            const hostFileList = yield this.hostService.getHostFileList(userId);
            client.emit('hostfilelist', hostFileList);
            // 规则列表
            const ruleFileList = yield this.ruleService.getRuleFileList(userId);
            client.emit('rulefilelist', ruleFileList);
            // 数据文件列表
            const dataList = yield this.mockDataService.getMockDataList(userId);
            client.emit('datalist', dataList);
        }));
        // proxy配置信息
        this.configureService.on('data-change', (userId, configure) => {
            socket.to(userId).emit('configure', configure);
        });
        // 个人配置信息
        this.profileService.on('data-change-profile', (userId, profile) => {
            socket.to(userId).emit('profile', profile);
        });
        this.profileService.on('data-change-clientIpUserMap', (userId, clientIpList) => {
            socket.to(userId).emit('mappedClientIps', clientIpList);
        });
        // host文件变化
        this.hostService.on('data-change', (userId, hostFilelist) => {
            socket.to(userId).emit('hostfilelist', hostFilelist);
        });
        // 规则文件列表
        this.ruleService.on('data-change', (userId, ruleFilelist) => {
            socket.to(userId).emit('rulefilelist', ruleFilelist);
        });
        // mock文件列表
        this.mockDataService.on('data-change', (userId, dataFilelist) => {
            socket.to(userId).emit('datalist', dataFilelist);
        });
    }
    // 通用函数，获取web socket连接中的用户id
    _getUserId(socketIOConn) {
        const cookies = cookie_1.default.parse(socketIOConn.request.headers.cookie || '');
        return cookies.userId || 'root';
    }
};
Manager = __decorate([
    typedi_1.Service(),
    __metadata("design:paramtypes", [])
], Manager);
exports.Manager = Manager;
//# sourceMappingURL=index.js.map