package org.bdware.analysis.example;

import org.bdware.analysis.taint.TaintCFG;
import org.bdware.analysis.taint.TaintResult;
import org.bdware.sc.compiler.YJSCompiler;
import org.bdware.sc.engine.DesktopEngine;
import org.bdware.sc.node.ContractNode;
import org.bdware.sc.node.FunctionNode;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;

public class NaiveTaintAnalysisTest extends NaiveTaintAnalysis {
    public NaiveTaintAnalysisTest(TaintCFG cfg) {
        super(cfg);
    }

    public static void main(String[] args) throws Exception {
        String path = "/Users/hulingxuan/git/SmartContract/output/main.yjs";
        // String tracePath = "/Users/hulingxuan/git/SmartContract/output/main.trace";
        ContractNode contractNode = null;
        YJSCompiler compiler = new YJSCompiler();
        contractNode = compiler.compile(new FileInputStream(path), null);
        DesktopEngine engine = new DesktopEngine();
        engine.loadContract(null,contractNode, false);
        Map<String, byte[]> clzs = engine.dumpClass();
        Map<String, MethodNode> methods = new HashMap<>();
        for (byte[] clz : clzs.values()) {
            ClassNode classNode = new ClassNode();
            ClassReader cr = new ClassReader(clz);
            cr.accept(classNode, ClassReader.EXPAND_FRAMES);
            for (MethodNode mn : classNode.methods) {
                methods.put(mn.name, mn);
            }
        }
        // for (FunctionNode fn : contractNode.getFunctions()) {
        // funNameList.add(fn.functionName);
        // }
        for (FunctionNode fn : contractNode.getFunctions()) {
            MethodNode mn = methods.get(fn.functionName);
            if (mn != null) {
                TaintResult.nLocals = mn.maxLocals;
                TaintResult.nStack = mn.maxStack;
                TaintCFG cfg = new TaintCFG(mn);
                // cfg.printSelf();
                // TracedFile tf = new TracedFile(new FileInputStream(tracePath));
                cfg.getLabelOrder();
                NaiveTaintAnalysis analysis = new NaiveTaintAnalysis(cfg);
                analysis.analysis();
                cfg.printSelf();
            }
        }
        //		String clzPath =
        // "./output/traceTest/wrp/jdk/nashorn/internal/scripts/Script$Recompilation$7$23A$contract_main_yjs7.class";
        //		// String clzPath =
        //		//
        // "/Users/damei/Documents/Project/DataContract/SmartContract/output/traceTest/wrp/jdk/nashorn/internal/scripts/Script$Recompilation$5$23A$contract_main_yjs5.class";
        //		ClassReader cr = new ClassReader(new FileInputStream(clzPath));
        //		ClassNode cn = new ClassNode();
        //		TaintResult.nLocals = 15;
        //		TaintResult.nStack = 5;
        //		cr.accept(cn, ClassReader.EXPAND_FRAMES);
        //		for (MethodNode mn : cn.methods) {
        //			if (mn.name.equals("statAge")) {
        //				System.out.println("[NaiveTaintAnalysis] Matched Method:" + mn.name + mn.desc);
        //				TaintCFG cfg = new TaintCFG(mn);
        //				TaintResult.printer.setLabelOrder(cfg.getLabelOrder());
        //				NaiveTaintAnalysis analysis = new NaiveTaintAnalysis(cfg);
        //				analysis.analysis();
        //				cfg.printSelf();
        //			}
        //		}
    }
}
