# coding: utf-8
# at.py
# address tree.

import os
CURRENT_DIRECTORY = os.path.split(os.path.realpath(__file__))[0]+'/'


class node:
	def __init__(self, data):
		self._data = data
		self._children = []

	def getdata(self):
		return self._data

	def getchildren(self):
		return self._children

	def add(self, node):
		self._children.append(node)

	def go(self, data):
		for child in self._children:
			if child.getdata() == data:
				return child
		return None

class tree:
	def __init__(self):
		self._head = node('header')

	def linktohead(self, node):
		self._head.add(node)

	def insert(self, path, data):
		cur = self._head
		for step in path:
			if cur.go(step) == None:
				return False
			else:
				cur = cur.go(step)
		cur.add(node(data))
		return True

	def search(self, path):
		cur = self._head
		for step in path:
			if cur.go(step) == None:
				return None
			else:
				cur = cur.go(step)
		return cur

def build_address_tree(dir_string_list=''):
	lt = tree()
	root = node(u'中国')
	lt.linktohead(root)
	path = [u'中国']
	for string in dir_string_list:
		x = depth_and_clear(string)
		path = path[:x[0]]
		x[1] = x[1].decode('utf-8')
		lt.insert(path, x[1])
		path.append(x[1])
	return lt

def depth_and_clear(string_with_space):
	i=0
	for string in string_with_space:
		if string == '	':
			i += 1
	string_with_space = string_with_space.replace('	', '')
	return [i,string_with_space]

def read_dir_string_list_from(filename):
	with open(filename, 'r') as f:
		r = list(map(lambda x:x.replace('\n', ''), f.readlines()))
		return r

def at():
	''' return an address tree. '''
	print 'building address tree.'
	import pickle
	address_tree_path = os.path.join(CURRENT_DIRECTORY, 'at.t')
	address_file_path = os.path.join(CURRENT_DIRECTORY, 'lt.txt')
	
	'''
	if not os.path.exists(address_tree_path):
		d = read_dir_string_list_from(address_file_path)
		t = build_address_tree(d)
		with open(address_tree_path,'wb') as f:
			pickle.dump(t, f)
		return t
	else:
		with open(address_tree_path, 'rb') as f:
			t = pickle.load(f)
		return t
	'''
	d = read_dir_string_list_from(address_file_path)
	t = build_address_tree(d)
	return t

def generate_regular_address_string(want_num = 2000, file_path = './ra.txt', to_country = True):
	import random
	import sys
	sys.path.append('../../src/')
	import small_char_set
	gb2312_path = '../hcl/GB2312_3755.txt'
	full_list = [i.rstrip('\n') for i in open(gb2312_path, 'r').readlines()]
	small_list = list(set(small_char_set.samll_char_set).intersection(set(full_list)))
	full_list = small_list
	t = at()
	path = [u'中国']
	addresses = []
	while len(addresses) < want_num:
		print len(addresses)
		try:
			prov = t.search(path).getchildren()[random.randrange(len(t.search(path).getchildren()))].getdata()
			path.append(prov)
			city = t.search(path).getchildren()[random.randrange(len(t.search(path).getchildren()))].getdata()
			path.append(city)
			county = t.search(path).getchildren()[random.randrange(len(t.search(path).getchildren()))].getdata()
			path.append(county)
			if to_country:
				town = t.search(path).getchildren()[random.randrange(len(t.search(path).getchildren()))].getdata()
				path.append(town)
				country = t.search(path).getchildren()[random.randrange(len(t.search(path).getchildren()))].getdata()
				path.append(country)
			else:
				pass
			
			a =''.join(path[1:])
			if sum([1 if i.encode('utf8') not in full_list else 0 for i in a])<=0:
				addresses.append(a)
				print a
			path = path[:1]
		except:
			path = path[:1]
			print 'search error'
	with open(file_path, 'w') as f:
		for i in addresses:
			f.write(i.encode('utf8')+'\n')
#generate_regular_address_string()
def validate(t, k_char_list, full_char_list):

	import sys
	sys.path.append('../../tools/')	
	import tools
	result = [full_char_list[i][0][0].decode('utf8') if k_char_list[i][0][0] == 'X' else k_char_list[i][0][0].decode('utf8') for i in range(len(full_char_list))]
	full_result = ''.join(result).encode('utf8')
	split_index = []
	try:
		path = [u'中国']
		index = 0
		while index < len(full_char_list):
			split_index.append(index)
			addresss = t.search(path).getchildren()
			addresssc = {}
			for i in addresss:
				x = i.getdata()
				sim = tools.levenshtein(result[index:index+len(x)], x)
				addresssc[sim] = x
			address = addresssc[max(addresssc.keys())]
			path.append(address)
			index += len(address)
		result = ''.join(path[1:]).encode('utf8')
	except:
		result = full_result
		split_index = [i for i in range(len(full_result))]
	return (result, full_result, split_index)