package org.bdware.analysis.taint;

import java.util.HashMap;
import java.util.Map;

public class TaintBits {
	Map<Long, String> data;
	Map<String, Long> type2Taint;
	long curr;
	Map<String, String> reallocate;
	int count = 0;

	public TaintBits() {
		curr = 1L;
		data = new HashMap<>();
		type2Taint = new HashMap<>();
		reallocate = new HashMap<>();
	}

	public long allocate(String type) {
		type = reallocateCall(type);
		if (type2Taint.containsKey(type))
			return type2Taint.get(type);
		long ret = curr;
		data.put(curr, type);
		type2Taint.put(type, curr);
		curr <<= 1;
		return ret;
	}

	private String reallocateCall(String type) {
		if (reallocate.containsKey(type))
			return reallocate.get(type);
		if (type.contains("dyn:call:executeContract")) {
			reallocate.put(type, "executeContract" + (count++));
			return reallocate.get(type);
		}
		return type;
	}

	public long getTaintValue(String type) {
		type = reallocateCall(type);
		if (type2Taint.containsKey(type))
			return type2Taint.get(type);
		return -1;
	}

	public String taintInfo() {
		String ret = "";
		long curr = this.curr >> 1;
		for (; curr >= 1L;) {
			ret += data.get(curr) + ", ";
			curr >>= 1;
		}
		return ret;
	}

	public String parse(long isTainted) {
		String ret = "";
		long curr = this.curr >> 1;
		for (; curr >= 1L;) {
			if ((isTainted & curr) != 0)
				ret += data.get(curr) + " ";
			curr >>= 1;
		}
		return ret;
	}
}
