const fs = require('fs');
const types = require("@babel/types");
const parser = require("@babel/parser");
const {log} = require('console');
const traverse = require("@babel/traverse").default;
const generator = require("@babel/generator").default;


//js混淆代码读取
process.argv.length > 2 ? encodeFile = process.argv[2] : encodeFile = "./shape.js";
process.argv.length > 3 ? decodeFile = process.argv[3] : decodeFile = "./out.js";

//将源代码解析为AST
let sourceCode = fs.readFileSync(encodeFile, {encoding: "utf-8"});

let ast = parser.parse(sourceCode, {sourceType: 'script'});

traverse(ast, {
    BinaryExpression(path){
        let {node} = path;
        let parent = path.parentPath.node;
        let {left, operator, right} = node;
        if (['>>>', '>>', '<', '>', '=', '+','-','*','/','^','&','%','<<','<<<','|','==','===','<=','>='].indexOf(operator) > -1){
            if(types.isMemberExpression(left) && types.isMemberExpression(right)){
                let {object: leftObject, property: leftproperty} = left;
                if (types.isMemberExpression(leftObject) && types.isBinaryExpression(leftproperty)){
                    if(types.isCallExpression(parent))return

                    debugger
                    path.parentPath.insertBefore(types.ExpressionStatement(
                        types.CallExpression(
                            // types.MemberExpression(types.Identifier('console'), types.Identifier('log')),
                            types.Identifier('con5'),
                            [
                                types.StringLiteral(generator(node).code),
                                left,
                                types.StringLiteral(operator),
                                right,
                                types.StringLiteral('='),
                                node
                            ]
                        )
                    ))
                    path.skip()

                }

            }else if (types.isIdentifier(left) && types.isIdentifier(right)){
                if(types.isAssignmentExpression(parent)){
                    let {left:inleft, right:inright, operator:inoperator} = parent;


                    path.parentPath.insertBefore(types.ExpressionStatement(
                        types.CallExpression(
                            // types.MemberExpression(types.Identifier('console'), types.Identifier('log')),
                            types.Identifier('con5'),
                            [
                                types.StringLiteral(generator(inleft).code),
                                types.Identifier(left.name),
                                types.StringLiteral(operator),
                                types.Identifier(right.name),
                                types.StringLiteral('='),
                                node
                            ]
                        )
                    ))

                }

            }else{
                    console.log(generator(parent).code)

            }

        }
    }
})

console.time("处理完毕，耗时");





console.timeEnd("处理完毕，耗时");



let {code} = generator(ast, opts = {jsescOption: {"minimal": true}});

fs.writeFile(decodeFile, code, (err) => {
});