#!/usr/bin/python

import pickle
import sys
import codecs

ENGLISH = 0
SPANISH = 1

FEMALE = 0
MALE = 1

AGES = [18, 25, 35, 50, 65]
GENDERS = [FEMALE, MALE]

# Represents the metadata of the dataset and provides functions to access
# the data associated with this metadata. User ids are integers, and we
# can translate from the hash-string ids to the integers used here with
# the function UserId.
class Meta:
	def __init__(self):
		self.ids = []
		self.num_convs = []
		self.lengths = []
		self.conv_fp = None
		self.conv_fp_len = -1
		self.conv_offset = []
		self.conv_ids = []
		self.langs = []
		self.genders = []
		self.ages = []

	# Retrieves the age of a user (10, 20, or 30)
	def GetAge(self, user_id):
		return self.ages[user_id]

	# Retrieves the gender of a given user
	def GetGender(self, user_id):
		return self.genders[user_id]

	# Retrieves the language in which a given user writes
	def GetLang(self, user_id):
		return self.langs[user_id]

	# Given a hash value, produces the number that is used as user id in this class
	def UserId(self, str_id):
		pos = bisect.bisect_left(self.ids, str_id)
		if pos == len(self.ids) or self.ids[pos] != str_id:
			return -1
		return pos
    	
    # Returns the number of conversations associated to user_id
	def GetNumDocuments(self, user_id):
		return self.num_convs[user_id]

	# Retrieves the content for the conversation number conv associated to user_id
	def GetDocument(self, user_id, conv):
		pos = self.conv_offset[user_id] + conv
		if pos == len(self.lengths):
			next = self.conv_fp_len
		else:
			next = self.lengths[pos + 1]
		return readFile(self.conv_fp, self.lengths[pos], next)

	# Retrieves the id for the conversation number conv associated to user user_id
	def GetDocumentId(self, user_id, conv):
		return self.conv_ids[user_id][conv]


# Reads a dataset generated by parse.py, takes in the basename of the files
def ReadMeta(basename):
	fp = open(basename+".meta")
	meta = pickle.load(fp)
	fp.close()
	meta.conv_fp = codecs.open(basename+".data","r","utf-8")
	meta.conv_fp.seek(0, 2)
	meta.conv_fp_len = meta.conv_fp.tell()
	return meta

# Obtains the integer value associated to an age range
# AgeStringToInt(AgeIntToString(x)) == x
def AgeStringToInt(age):
	if age == "18-24": return 18
	if age == "25-34": return 25
	if age == "35-49": return 35
	if age == "50-64": return 50
	if age == "65-xx": return 65

# Obtains the string range associated to an integer value
# AgeIntToString(AgeStringToInt(x)) == x
def AgeIntToString(age):
	if age == 18: return "18-24"
	if age == 25: return "25-34"
	if age == 35: return "35-49"
	if age == 50: return "50-64"
	if age == 65: return "65-xx"

# Reads file fp between positions [ini, fin]
def readFile(fp, ini, fin):
	fp.seek(ini)
	return fp.read(fin - ini + 1)


# Main that dumps the content of a meta file
if __name__ == "__main__":
	if len(sys.argv) != 2:
		print "usage: %s <basename>" % (sys.argv[0])
		sys.exit(0)

	meta = ReadMeta(sys.argv[1])
	for i in xrange(len(meta.ids)):
		print "User id %s (age: %d, gender: %d, lang: %d)" % (meta.ids[i], meta.GetAge(i), meta.GetGender(i), meta.GetLang(i))
		print "Number of conversations: %d" % (meta.GetNumDocuments(i))
		print "Conversations: "
		for j in xrange(meta.GetNumDocuments(i)):
			print "%d (%s) :: %s" % (j, meta.GetDocumentId(i, j), meta.GetDocument(i, j))
