#include "ace.h"
#include "sim.h"

#include "cudd.h"

void get_pi_values(Abc_Ntk_t * ntk, Vec_Ptr_t * nodes, int cycle) {
	Abc_Obj_t * obj;
	Ace_Obj_Info_t * info;
	int i;
	double prob0to1, prob1to0, rand_num;

	//Vec_PtrForEachEntry(Abc_Obj_t *, nodes, obj, i)
	Abc_NtkForEachObj(ntk, obj, i)
	{
		info = Ace_ObjInfo(obj);
		if (Abc_ObjType(obj) == ABC_OBJ_PI) {
			if (info->values) {
				if (info->status == ACE_UNDEF) {
					info->status = ACE_NEW;
					if (info->values[cycle] == 1) {
						info->value = 1;
						info->num_toggles = 1;
						info->num_ones = 1;
					} else {
						info->value = 0;
						info->num_toggles = 0;
						info->num_ones = 0;
					}
				} else {
					switch (info->value) {
					case 0:
						if (info->values[cycle] == 1) {
							info->value = 1;
							info->status = ACE_NEW;
							info->num_toggles++;
							info->num_ones++;
						} else {
							info->status = ACE_OLD;
						}
						break;

					case 1:
						if (info->values[cycle] == 0) {
							info->value = 0;
							info->status = ACE_NEW;
							info->num_toggles++;
						} else {
							info->num_ones++;
							info->status = ACE_OLD;
						}
						break;

					default:
						printf("Bad Value\n");
						assert(0);
						break;
					}
				}
			} else {
				prob0to1 = ACE_P0TO1(info->static_prob, info->switch_prob);
				prob1to0 = ACE_P1TO0(info->static_prob, info->switch_prob);

				rand_num = (double) rand() / (double) RAND_MAX;

				if (info->status == ACE_UNDEF) {
					info->status = ACE_NEW;
					if (rand_num < prob0to1) {
						info->value = 1;
						info->num_toggles = 1;
						info->num_ones = 1;
					} else {
						info->value = 0;
						info->num_toggles = 0;
						info->num_ones = 0;
					}
				} else {
					switch (info->value) {
					case 0:
						if (rand_num < prob0to1) {
							info->value = 1;
							info->status = ACE_NEW;
							info->num_toggles++;
							info->num_ones++;
						} else {
							info->status = ACE_OLD;
						}
						break;

					case 1:
						if (rand_num < prob1to0) {
							info->value = 0;
							info->status = ACE_NEW;
							info->num_toggles++;
						} else {
							info->num_ones++;
							info->status = ACE_OLD;
						}
						break;

					default:
						printf("Bad value\n");
						assert(FALSE);
						break;
					}
				}
			}
		}
	}
}

int * getFaninValues(Abc_Obj_t * obj_ptr) {
	Abc_Obj_t * fanin;
	int i;
	Ace_Obj_Info_t * info;
	int * faninValues;

	Abc_ObjForEachFanin(obj_ptr, fanin, i)
	{
		info = Ace_ObjInfo(fanin);
		if (info->status == ACE_UNDEF) {
			printf("Fan-in is undefined\n");
			assert(FALSE);
		} else if (info->status == ACE_NEW) {
			break;
		}
	}

	if (i >= Abc_ObjFaninNum(obj_ptr)) {
		// inputs haven't changed
		return NULL;
	}

	faninValues = malloc(Abc_ObjFaninNum(obj_ptr) * sizeof(int));
	Abc_ObjForEachFanin(obj_ptr, fanin, i)
	{
		info = Ace_ObjInfo(fanin);
		faninValues[i] = info->value;
	}

	return faninValues;
}

ace_status_t getFaninStatus(Abc_Obj_t * obj_ptr) {
	Abc_Obj_t * fanin;
	int i;
	Ace_Obj_Info_t * info;

	Abc_ObjForEachFanin(obj_ptr, fanin, i)
	{
		info = Ace_ObjInfo(fanin);
		if (info->status == ACE_UNDEF) {
			return ACE_UNDEF;
		}
	}

	Abc_ObjForEachFanin(obj_ptr, fanin, i)
	{
		info = Ace_ObjInfo(fanin);
		if (info->status == ACE_NEW || info->status == ACE_SIM) {
			return ACE_NEW;
		}
	}

	return ACE_OLD;
}

void evaluate_circuit(Abc_Ntk_t * ntk, Vec_Ptr_t * node_vec, int cycle) {
	Abc_Obj_t * obj;
	Ace_Obj_Info_t * info;
	int i;
	int value;
	int * faninValues;
	ace_status_t status;
	DdNode * dd_node;

	Vec_PtrForEachEntry(node_vec, obj, i)
	{
		info = Ace_ObjInfo(obj);

		switch (Abc_ObjType(obj)) {
		case ABC_OBJ_PI:
		case ABC_OBJ_BO:
			break;

		case ABC_OBJ_PO:
		case ABC_OBJ_BI:
		case ABC_OBJ_LATCH:
		case ABC_OBJ_NODE:
			status = getFaninStatus(obj);
			switch (status) {
			case ACE_UNDEF:
				info->status = ACE_UNDEF;
				break;
			case ACE_OLD:
				info->status = ACE_OLD;
				info->num_ones += info->value;
				break;
			case ACE_NEW:
				if (Abc_ObjIsNode(obj)) {
					faninValues = getFaninValues(obj);
					assert(faninValues);
					dd_node = Cudd_Eval(ntk->pManFunc, obj->pData, faninValues);
					assert(Cudd_IsConstant(dd_node));
					if (dd_node == Cudd_ReadOne(ntk->pManFunc)) {
						value = 1;
					} else if (dd_node == Cudd_ReadLogicZero(ntk->pManFunc)) {
						value = 0;
					} else {
						assert(0);
					}
					free(faninValues);
				} else {
					Ace_Obj_Info_t * fanin_info = Ace_ObjInfo(
							Abc_ObjFanin0(obj));
					value = fanin_info->value;
				}

				if (info->value != value || info->status == ACE_UNDEF) {
					info->value = value;
					if (info->status != ACE_UNDEF) {
						/* Don't count the first value as a toggle */
						info->num_toggles++;
					}
					info->status = ACE_NEW;
				} else {
					info->status = ACE_OLD;
				}
				info->num_ones += info->value;
				break;
			default:
				assert(0);
				break;
			}
			break;
		default:
			assert(0);
			break;
		}
	}
}

void update_FFs(Abc_Ntk_t * ntk) {
	Abc_Obj_t * obj;
	int i;
	Ace_Obj_Info_t * bi_fanin_info;
	Ace_Obj_Info_t * bi_info;
	Ace_Obj_Info_t * latch_info;
	Ace_Obj_Info_t * bo_info;

	Abc_NtkForEachLatch(ntk, obj, i)
	{
		bi_fanin_info = Ace_ObjInfo(Abc_ObjFanin0(Abc_ObjFanin0(obj)));
		bi_info = Ace_ObjInfo(Abc_ObjFanin0(obj));
		bo_info = Ace_ObjInfo(Abc_ObjFanout0(obj));
		latch_info = Ace_ObjInfo(obj);

		// Value
		bi_info->value = bi_fanin_info->value;
		latch_info->value = bi_fanin_info->value;
		bo_info->value = bi_fanin_info->value;

		// Status
		bi_info->status = bi_fanin_info->status;
		latch_info->status = bi_fanin_info->status;
		bo_info->status = bi_fanin_info->status;

		// Ones
		bi_info->num_ones = bi_fanin_info->num_ones;
		latch_info->num_ones = bi_fanin_info->num_ones;
		bo_info->num_ones = bi_fanin_info->num_ones;

		// Toggles
		bi_info->num_toggles = bi_fanin_info->num_toggles;
		latch_info->num_toggles = bi_fanin_info->num_toggles;
		bo_info->num_toggles = bi_fanin_info->num_toggles;
	}
}

void ace_sim_activities(Abc_Ntk_t * ntk, Vec_Ptr_t * nodes, int max_cycles,
		double threshold) {
	Abc_Obj_t * obj;
	Ace_Obj_Info_t * info;
	int i;

	assert(max_cycles > 0);
	assert(threshold > 0.0);

	srand((unsigned) time(NULL));

	//Vec_PtrForEachEntry(Abc_Obj_t *, nodes, obj, i)
	Abc_NtkForEachObj(ntk, obj, i)
	{
		info = Ace_ObjInfo(obj);
		info->value = 0;

		if (Abc_ObjType(obj) == ABC_OBJ_BO) {
			info->status = ACE_NEW;
		} else {
			info->status = ACE_UNDEF;
		}
		info->num_ones = 0;
		info->num_toggles = 0;
	}

	Vec_Ptr_t * logic_nodes = Abc_NtkDfs(ntk, TRUE);
	for (i = 0; i < max_cycles; i++) {
		get_pi_values(ntk, nodes, i);
		evaluate_circuit(ntk, logic_nodes, i);
		update_FFs(ntk);
	}

	//Vec_PtrForEachEntry(Abc_Obj_t *, nodes, obj, i)
	Abc_NtkForEachObj(ntk, obj, i)
	{
		info = Ace_ObjInfo(obj);
		info->static_prob = info->num_ones / (double) max_cycles;
		assert(info->static_prob >= 0.0 && info->static_prob <= 1.0);
		info->switch_prob = info->num_toggles / (double) max_cycles;
		assert(info->switch_prob >= 0.0 && info->switch_prob <= 1.0);

		assert(info->switch_prob - EPSILON <= 2.0 * (1.0 - info->static_prob));
		assert(info->switch_prob - EPSILON <= 2.0 * (info->static_prob));

		info->status = ACE_SIM;
	}
}
