"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 es6_promisify_1 = require("es6-promisify");
const events_1 = __importDefault(require("events"));
const fs_1 = __importDefault(require("fs"));
const jsonfile_1 = __importDefault(require("jsonfile"));
const lodash_1 = require("lodash");
const path_1 = __importDefault(require("path"));
const typedi_1 = require("typedi");
const appInfo_1 = require("./appInfo");
const jsonfileWriteFile = es6_promisify_1.promisify(jsonfile_1.default.writeFile);
const fsReadFile = es6_promisify_1.promisify(fs_1.default.readFile);
const fsWriteFile = es6_promisify_1.promisify(fs_1.default.writeFile);
const fsUnlink = es6_promisify_1.promisify(fs_1.default.unlink);
/**
 * 数据mock
 */
let MockDataService = class MockDataService extends events_1.default {
    constructor(appInfoService) {
        super();
        const proxyDataDir = appInfoService.getProxyDataDir();
        // 存放mock data的目录
        this.mockDataDir = path_1.default.join(proxyDataDir, 'mock-data');
        this.mockListDir = path_1.default.join(proxyDataDir, 'mock-list');
        // userId -> datalist
        this.mockDataList = {};
        const contentMap = fs_1.default
            .readdirSync(this.mockListDir)
            .filter(name => name.endsWith('.json'))
            .reduce((prev, curr) => {
            prev[curr] = jsonfile_1.default.readFileSync(path_1.default.join(this.mockListDir, curr));
            return prev;
        }, {});
        lodash_1.forEach(contentMap, (content, fileName) => {
            const userId = fileName.slice(0, -5);
            this.mockDataList[userId] = content;
        });
    }
    /**
     * 获取数据文件内容
     * @param clientIp
     * @param dataId
     */
    getDataFileContent(userId, dataId) {
        return __awaiter(this, void 0, void 0, function* () {
            const dataFilePath = this._getDataFilePath(userId, dataId);
            try {
                return yield fsReadFile(dataFilePath, { encoding: 'utf-8' });
            }
            catch (e) {
                return '';
            }
        });
    }
    /**
     * 获取数据文件的 content type
     * {id:'',contenttype:'',name:''}
     * @returns {*}
     */
    getDataFileContentType(userId, dataId) {
        return __awaiter(this, void 0, void 0, function* () {
            const list = this.mockDataList[userId];
            // 寻找
            const finded = lodash_1.find(list, entry => {
                return entry.id === dataId;
            });
            if (!finded) {
                return '';
            }
            return finded.contenttype + ';charset=utf-8';
        });
    }
    /**
     * 获取某个用户的数据列表
     * @param userId
     * @returns {*}
     */
    getMockDataList(userId) {
        return this.mockDataList[userId] || [];
    }
    setMockDataList(userId, mocklist) {
        return __awaiter(this, void 0, void 0, function* () {
            this.mockDataList[userId] = mocklist;
            const listFilePath = this._getMockEntryPath(userId);
            yield jsonfileWriteFile(listFilePath, mocklist, { encoding: 'utf-8' });
            // 发送消息通知
            this.emit('data-change', userId, this.getMockDataList(userId));
        });
    }
    /**
     * 保存数据文件列表，清除无用的数据文件
     * @param userId
     * @param dataList
     */
    saveMockDataList(userId, dataList) {
        return __awaiter(this, void 0, void 0, function* () {
            // 找出要被被删除的数据文件, 老的数据文件里有，而新的没有
            const newDataKeys = new Set();
            const toRemove = [];
            dataList.forEach(data => {
                newDataKeys.add(data.id);
            });
            const originMockDataList = this.getMockDataList(userId);
            originMockDataList.forEach(data => {
                if (!newDataKeys.has(data.id)) {
                    toRemove.push(data.id);
                }
            });
            // 设置新值
            yield this.setMockDataList(userId, dataList);
            // 删除文件
            for (const rId of toRemove) {
                const dataPath = this._getDataFilePath(userId, rId);
                yield fsUnlink(dataPath);
            }
        });
    }
    /**
     * 用户保存数据文件
     * @param userId
     * @param dataFileId
     * @param content
     */
    saveDataFileContent(userId, dataFileId, content) {
        return __awaiter(this, void 0, void 0, function* () {
            const dataFilePath = this._getDataFilePath(userId, dataFileId);
            yield fsWriteFile(dataFilePath, content, { encoding: 'utf-8' });
        });
    }
    /**
     * 用户从监控窗保存一个数据文件
     */
    saveDataEntryFromTraffic(userId, dataFileId, fileName, contentType, content) {
        return __awaiter(this, void 0, void 0, function* () {
            const dataList = this.mockDataList[userId] || [];
            dataList.push({
                contenttype: contentType,
                id: dataFileId,
                name: fileName,
            });
            // 保存mock数据文件列表
            const listFilePath = this._getMockEntryPath(userId);
            yield jsonfileWriteFile(listFilePath, dataList, { encoding: 'utf-8' });
            // 保存数据文件
            const dataFilePath = this._getDataFilePath(userId, dataFileId);
            yield fsWriteFile(dataFilePath, content, { encoding: 'utf-8' });
        });
    }
    /**
     * 获取数据文件路径
     * @param userId
     * @param dataId
     * @private
     */
    _getDataFilePath(userId, dataId) {
        const p = path_1.default.join(this.mockDataDir, userId + '_' + dataId);
        if (!fs_1.default.existsSync(p)) {
            return p;
        }
        const dataFileRealPath = fs_1.default.realpathSync(p);
        if (dataFileRealPath.includes(this.mockDataDir)) {
            return p;
        }
        else {
            return '';
        }
    }
    /**
     * 获取数据文件列表
     * @param userId
     * @private
     */
    _getMockEntryPath(userId) {
        return path_1.default.join(this.mockListDir, userId + '.json');
    }
};
MockDataService = __decorate([
    typedi_1.Service(),
    __metadata("design:paramtypes", [appInfo_1.AppInfoService])
], MockDataService);
exports.MockDataService = MockDataService;
//# sourceMappingURL=mockData.js.map