#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import string

import nltk.corpus
import nltk.tree
import simplejson as json
from config.constant import Values

import semantic.behavior
import operations.scene
import strfilters.tokenizer
from packager.base import BaseProcessor
from gensim.models import KeyedVectors
from nltk.corpus import wordnet as wn

class UIBehaviorProcessor(BaseProcessor):
	@staticmethod
	def process(tainted_groups):
		logger = logging.getLogger(__name__)
		logger.debug("[Behavior] starts to extract behaviors")
		groups = tainted_groups
		processed_tainted_groups = []

		groups_length = len(groups)
		print_interval = 0.05
		last_print = print_interval
		
		model = KeyedVectors.load(Values.word2vec_model_path)

		for i, group in enumerate(groups):
			processed_tainted_groups.append(
		        _UIGroupBehaviorProcessor.process(group,model))

			processed_percentage = float(i) / groups_length
			if processed_percentage >= last_print:
			    logger.debug(
			        "[Behavior] processed:{percentage:.2f}%({i}/{len})".format(
			            percentage=100 * (float(i) / groups_length), i=i,
			            len=groups_length))
			    last_print += print_interval
		return processed_tainted_groups


class _UIGroupBehaviorProcessor(BaseProcessor):
	@staticmethod
	def get_keywords(initial_words,model):
		# api_descr_behaviors = BehaviorHandler.process(api_descr)
		# keywords = set()
		# keywords.update(api_descr_behaviors.actions)
		# keywords.update(api_descr_behaviors.resources)
		keywords = set()
		word_filter = operations.scene.Scene().similarity_processor_stopwords
		for res in initial_words:
			if res in word_filter:
				continue
			try:
				similar_res = [x[0] for x in model.wv.most_similar(res,topn=30)]
			except (KeyError):
				similar_res = set()
			keywords.update(similar_res)
		keywords.update(initial_words)
		return keywords

	@staticmethod
	def process(tainted_group,model):
		logger = logging.getLogger(__name__)

		keywords = set()
		if tainted_group.app_descr.behaviors:
			keywords.update(tainted_group.app_descr.behaviors.actions)
			keywords.update(tainted_group.app_descr.behaviors.resources)
		if tainted_group.api_cls_descr.behaviors:
			keywords.update(tainted_group.api_cls_descr.behaviors.actions)
			keywords.update(tainted_group.api_cls_descr.behaviors.resources)
		if tainted_group.api_mtd_descr.behaviors:
			keywords.update(tainted_group.api_mtd_descr.behaviors.actions)
			keywords.update(tainted_group.api_mtd_descr.behaviors.resources)

		keywords = _UIGroupBehaviorProcessor.get_keywords(keywords,model)

		tainted_texts = [tainted_group.json_string,
		                 tainted_group.refer_keywords,
		                 tainted_group.layout_strings]
		
		for i in range(len(tainted_texts)):
			if tainted_texts[i].is_skip:
				continue
			behavior_pairs_list = list()
			resources = set()
			actions = set()
			text = tainted_texts[i].raw
			if text is not None:
				texts = text.split('+*-+*-')
				for tx in texts:
					keys = set()
					tx = tx.lower()
					for keyword in keywords:
						if keyword in tx:
							keys.add(keyword)
					if len(keys)>0:
						tmp_acts = set()
						tmp_res = set()
						for word in keys:
							pos_l = set()
							try:
								# tmp = wn.synsets(word)[0].pos()
								for tmp in wn.synsets(word):
									if tmp.name().split('.')[0] == word:
										pos_l.add(tmp.pos())
							except Exception as e:
								continue
							# print word, ":", pos_l
							# exit()
							if 'v' in pos_l:
								tmp_acts.add(word)
							elif 'n' in pos_l:
								tmp_res.add(word)
						if len(tmp_acts)>0 and len(tmp_res)==0:
							behavior_pairs_list.extend(tmp_acts)
							actions.update(tmp_acts)
						elif len(tmp_acts)==0 and len(tmp_res)>0:
							behavior_pairs_list.extend(tmp_res)
							resources.update(tmp_res)							
						elif len(tmp_acts)>0 and len(tmp_res)>0:
							actions.update(tmp_acts)
							resources.update(tmp_res)							
							for act in tmp_acts:
								for res in tmp_res:
									behavior_pairs_list.append(act+' '+res)

			# print(actions)
			# print(resources)
			# print(behavior_pairs_list)

			tainted_texts[i].behaviors = semantic.behavior.Behavior(
				pairs=behavior_pairs_list, actions=actions, resources=resources)
		# print(keywords)

		# exit()
		return tainted_group