from liblinearutil_xiao import *
from active_learning import *
from check_dataset import *

def get_all_used_docs(fname, labelIndex, parents):
	docs = []
	n_index = 0
	fd = open(fname)
	for line in fd:
		line = line.strip().split(' ')
		id = line[0]
		num_label = int(line[1])
		labels = line[2:]
		labels = [int(l) for l in labels]
		labels = set(labels)
		labels.add(-1)
		if labelIndex in labels:
			#positive
			docs.append((id, n_index, 1))
		else:#negative
			par = parents[labelIndex]
			if par == 0 or par in labels:
				docs.append((id, n_index, -1))
		n_index += 1
	fd.close()
	return docs

def read_problem_feature(docs, fname):
	id_used = set([d[0] for d in docs])	
	x = []	
	fd = open(fname)
	for line in fd:
		line = line.strip().split(' ')
		id = line[0]
		if id in id_used:
			features = {}
			for l in line[1:]:
				wd, v = l.split(':')
				features[int(wd)] = float(v)
			x.append(features)
	fd.close()
	return x

def select_problem_TF_feature(indices, features):
	ret_features = []	
	for index in range(len(features)):
		if index in indices:			
			ret_features.append(dict(features[index]))#make a copy here
	return ret_features
	
def read_selected_problem_TF_feature(docs, fname):
	id_used = set([d[0] for d in docs])	
	x = []	
	fd = open(fname)
	for line in fd:
		line = line.strip().split(' ')
		id = line[0]
		if id in id_used:			
			words = []
			occs = []
			for l in line[1:]:
				wd, v = l.split(':')
				words.append(int(wd))
				occs.append(int(v))
			#do normalization
			sm = sum(occs)
			occs = [float(o)/sm for o in occs]
			features = {}
			for i in range(len(words)):
				features[words[i]] = occs[i]
			#append examples			
			x.append(features)
	fd.close()
	return x

def get_max_feature(fname):
	max_f = -1
	fd = open(fname)
	for line in fd:
		line = line.strip().split(' ')
		id = line[0]			
		for l in line[1:]:
			wd, v = l.split(':')
			if int(wd) > max_f:
				max_f = int(wd)		
	fd.close()
	return max_f

def read_problem_id(docs):
	ids = [int(d[0]) for d in docs]
	return ids

def read_problem_index(docs):
	indices = [int(d[1]) for d in docs]
	return indices
				
def read_problem_label(docs):
	y = [d[2] for d in docs]
	return y

def read_problem_feature(fname):	
	x = []
	fd = open(fname)
	for line in fd:
		line = line.strip().split(' ')
		id = line[0]		
		features = {}		
		for l in line[1:]:
			wd, v = l.split(':')
			features[int(wd)] = float(v)
		x.append(features)
	fd.close()
	return x	

def read_problem_TF_feature(fname):	
	x = []
	fd = open(fname)
	for line in fd:
		line = line.strip().split(' ')
		id = line[0]		
		words = []
		occs = []
		for l in line[1:]:
			wd, v = l.split(':')
			words.append(int(wd))
			occs.append(int(v))
		#do normalization
		sm = sum(occs)
		occs = [float(o)/sm for o in occs]
		features = {}
		for i in range(len(words)):
			features[words[i]] = occs[i]
		x.append(features)
	fd.close()
	return x
	
def write_list_to_file(data, fname):
	fd = open(fname, 'w')
	for d in data:
		v = '%.4f' % d
		fd.write(v + '\n')
	fd.close()

def get_silbing(c, parents):
	sib = []
	my_parent = parents[c]
	for nd in parents:
		if parents[nd] == my_parent:
			sib.append(nd)
	return sib

def read_used_probs(fname, used_indices):
	probs = []
	index = 0
	fd = open(fname)
	for line in fd:
		if index in used_indices:			
			p = float(line.strip())
			probs.append(p)
		index += 1
	fd.close()
	return probs
	
def read_used_probs_by_id(fname, used_id_set):
	probs = []	
	fd = open(fname)
	for line in fd:
		line = line.strip().split(' ')
		did = int(line[0])
		prob = float(line[1])
		if did in used_id_set:			
			probs.append(prob)		
	fd.close()
	return probs

def read_probs(fname):
	probs = []	
	fd = open(fname)
	for line in fd:		
		p = float(line.strip())
		probs.append(p)
	fd.close()
	return probs
	
def prob_dict_to_lst(probs):
	all_cats = probs.keys()
	all_cats.sort()
	lst = []
	n_probs = len(probs[all_cats[0]])
	for i in range(n_probs):
		lst.append([probs[c][i] for c in all_cats])
	return lst

def compute_loss_with_labels(pred_labels, labels):
	tp = 0
	fp = 0
	fn = 0
	for i in range(len(pred_labels)):
		if pred_labels[i] == 1:
			p = 1
		else:
			p = -1
		l = labels[i]
		if p == 1 and l == 1:
			tp += 1
		elif p == 1 and l == -1:
			fp += 1
		elif p == -1 and l == 1:
			fn += 1
	if tp + fp != 0:
		pre = float(tp)/(tp + fp)
	else:
		pre = 0
	if tp + fn != 0:
		rec = float(tp)/(tp + fn)
	else:
		rec = 0
	if pre + rec == 0:
		f1 = 0
	else:
		f1 = 2* pre * rec / (pre + rec)
	return tp, fp, fn, pre, rec, f1
	
def compute_loss(probs, labels, threshold):
	tp = 0
	fp = 0
	fn = 0
	for i in range(len(probs)):
		if probs[i] >= threshold:
			p = 1
		else:
			p = -1
		l = labels[i]
		if p == 1 and l == 1:
			tp += 1
		elif p == 1 and l == -1:
			fp += 1
		elif p == -1 and l == 1:
			fn += 1
	if tp + fp != 0:
		pre = float(tp)/(tp + fp)
	else:
		pre = 0
	if tp + fn != 0:
		rec = float(tp)/(tp + fn)
	else:
		rec = 0
	if pre + rec == 0:
		f1 = 0
	else:
		f1 = 2* pre * rec / (pre + rec)
	return tp, fp, fn, pre, rec, f1
				
def usage():
	print 'cmd --hier fname1 --trfeature fname2 --trlabel fname3 --tefeature fname4 --telabel fname4 --modelfolder --predictionfolder --trainpredictionfolder'

def check_first_positive(x, y):
	if len(y) > 1:
		if y[0] == -1:
			#find the first positive
			for i in range(len(y)):
				if y[i] == 1:
					break
			if i < len(y):
				tmp = y[0]
				y[0] = y[i]
				y[i] = tmp
				tmp = x[0]
				x[0] = x[i]
				x[i] = tmp
				
def read_labels(fname):
	labels = []
	fd = open(fname)
	for line in fd: