/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
///<reference path='../ts-declarations/node.d.ts' />
var fs = require('fs');
/**
 * this only works for small traces; reads the whole thing into memory
 * @param filename
 * @returns {string}
 */
function parseTrace(filename) {
    var result = "";
    var binTrace = fs.readFileSync(filename);
    var offset = 0;
    var readInt = function (noComma) {
        result += binTrace.readInt32BE(offset);
        if (!noComma)
            result += ',';
        offset += 4;
    };
    var readString = function (noComma) {
        var strLen = binTrace.readInt32BE(offset);
        offset += 4;
        result += JSON.stringify(binTrace.toString('utf16le', offset, offset + strLen));
        if (!noComma)
            result += ',';
        offset += strLen;
    };
    while (offset < binTrace.length) {
        result += '[';
        var entryType = binTrace[offset++];
        result += entryType + ',';
        switch (entryType) {
            case 0 /* DECLARE */:
                readInt();
                readString();
                readInt(true);
                break;
            case 1 /* CREATE_OBJ */:
                readInt();
                readInt(true);
                break;
            case 2 /* CREATE_FUN */:
                readInt();
                readInt();
                readInt(true);
                break;
            case 3 /* PUTFIELD */:
                readInt();
                readInt();
                readString();
                readInt(true);
                break;
            case 4 /* WRITE */:
                readInt();
                readString();
                readInt(true);
                break;
            case 5 /* LAST_USE */:
                readInt();
                readInt();
                readInt(true);
                break;
            case 6 /* FUNCTION_ENTER */:
                readInt();
                readInt(true);
                break;
            case 7 /* FUNCTION_EXIT */:
                readInt(true);
                break;
            case 8 /* TOP_LEVEL_FLUSH */:
                readInt(true);
                break;
            case 9 /* UPDATE_IID */:
                readInt();
                readInt(true);
                break;
            case 10 /* DEBUG */:
                readInt();
                readInt(true);
                break;
            case 11 /* RETURN */:
                readInt(true);
                break;
            case 12 /* CREATE_DOM_NODE */:
                readInt();
                readInt(true);
                break;
            case 13 /* ADD_DOM_CHILD */:
                readInt();
                readInt(true);
                break;
            case 14 /* REMOVE_DOM_CHILD */:
                readInt();
                readInt(true);
                break;
            case 15 /* ADD_TO_CHILD_SET */:
                readInt();
                readInt();
                readString();
                readInt(true);
                break;
            case 16 /* REMOVE_FROM_CHILD_SET */:
                readInt();
                readInt();
                readString();
                readInt(true);
                break;
            case 17 /* DOM_ROOT */:
                readInt(true);
                break;
            case 18 /* CALL */:
                readInt();
                readInt();
                readInt(true);
                break;
            case 19 /* SCRIPT_ENTER */:
                readInt();
                readString(true);
                break;
            case 20 /* SCRIPT_EXIT */:
                readInt(true);
                break;
            case 21 /* FREE_VARS */:
                readInt();
                var arrLength = binTrace.readInt32BE(offset);
                offset += 4;
                if (arrLength === -1) {
                    // string
                    readString(true);
                }
                else {
                    var arr = [];
                    for (var ind = 0; ind < arrLength; ind++) {
                        var strLen = binTrace.readInt32BE(offset);
                        offset += 4;
                        arr.push(binTrace.toString('utf16le', offset, offset + strLen));
                        offset += strLen;
                    }
                    result += JSON.stringify(arr);
                }
                break;
            case 22 /* SOURCE_MAPPING */:
                readInt();
                readString();
                readInt();
                readInt(true);
                break;
        }
        result += ']\n';
    }
    return result;
}
exports.parseTrace = parseTrace;
// IID special values: -1 is unknown, -2 corresponds to the initial
// DOM traversal to attach mutation observers
var LogEntryType;
(function (LogEntryType) {
    LogEntryType[LogEntryType["DECLARE"] = 0] = "DECLARE";
    LogEntryType[LogEntryType["CREATE_OBJ"] = 1] = "CREATE_OBJ";
    LogEntryType[LogEntryType["CREATE_FUN"] = 2] = "CREATE_FUN";
    LogEntryType[LogEntryType["PUTFIELD"] = 3] = "PUTFIELD";
    LogEntryType[LogEntryType["WRITE"] = 4] = "WRITE";
    LogEntryType[LogEntryType["LAST_USE"] = 5] = "LAST_USE";
    LogEntryType[LogEntryType["FUNCTION_ENTER"] = 6] = "FUNCTION_ENTER";
    LogEntryType[LogEntryType["FUNCTION_EXIT"] = 7] = "FUNCTION_EXIT";
    LogEntryType[LogEntryType["TOP_LEVEL_FLUSH"] = 8] = "TOP_LEVEL_FLUSH";
    LogEntryType[LogEntryType["UPDATE_IID"] = 9] = "UPDATE_IID";
    LogEntryType[LogEntryType["DEBUG"] = 10] = "DEBUG";
    LogEntryType[LogEntryType["RETURN"] = 11] = "RETURN";
    LogEntryType[LogEntryType["CREATE_DOM_NODE"] = 12] = "CREATE_DOM_NODE";
    LogEntryType[LogEntryType["ADD_DOM_CHILD"] = 13] = "ADD_DOM_CHILD";
    LogEntryType[LogEntryType["REMOVE_DOM_CHILD"] = 14] = "REMOVE_DOM_CHILD";
    LogEntryType[LogEntryType["ADD_TO_CHILD_SET"] = 15] = "ADD_TO_CHILD_SET";
    LogEntryType[LogEntryType["REMOVE_FROM_CHILD_SET"] = 16] = "REMOVE_FROM_CHILD_SET";
    LogEntryType[LogEntryType["DOM_ROOT"] = 17] = "DOM_ROOT";
    LogEntryType[LogEntryType["CALL"] = 18] = "CALL";
    LogEntryType[LogEntryType["SCRIPT_ENTER"] = 19] = "SCRIPT_ENTER";
    LogEntryType[LogEntryType["SCRIPT_EXIT"] = 20] = "SCRIPT_EXIT";
    LogEntryType[LogEntryType["FREE_VARS"] = 21] = "FREE_VARS";
    LogEntryType[LogEntryType["SOURCE_MAPPING"] = 22] = "SOURCE_MAPPING"; // fields: iid, filename, startLine, startColumn
})(LogEntryType || (LogEntryType = {}));
if (require.main === module) {
    parseTrace(process.argv[2]);
}
//# sourceMappingURL=binaryTraceParser.js.map