"""
Script generates statistics for path and function names in projects
"""

import ast
import os
import collections
import sys
from nltk import pos_tag
from helpers import *
from git import Repo
import argparse

def is_verb(word):
	if not word:
		return False
	pos_info = pos_tag([word])
	return pos_info[0][1] == 'VB'


def get_trees(path, with_filenames=False, with_file_content=False):
	filenames = []
	trees = []
	for dirname, dirs, files in os.walk(path, topdown=True):
		for filename in files:
			if filename.endswith('.py'):
				filenames.append(os.path.join(dirname, filename))
				if len(filenames) == 100:
					break
	print('%s total files' % len(filenames))
	for filename in filenames:
		with open(filename, 'r', encoding='utf-8') as attempt_handler:
			main_file_content = attempt_handler.read()
		try:
			tree = ast.parse(main_file_content)
		except SyntaxError as e:
			print(e)
			tree = None
		if with_filenames and with_file_content:
			trees.append((filename, main_file_content, tree))
		elif with_filenames:
			trees.append((filename, tree))
		else:
			trees.append(tree)
	print('Trees for path generated')
	return trees


def get_all_names(tree):
	# print([node.id for node in ast.walk(tree) if isinstance(node, ast.Name)])
	return [node.id for node in ast.walk(tree) if isinstance(node, ast.Name)]


def get_function_names_in_tree(tree):
	return [node.name.lower() for node in ast.walk(tree) if isinstance(node, ast.FunctionDef)]


def get_verbs_from_function_name(function_name):
	return [word for word in function_name.split('_') if is_verb(word)]


def get_all_words_in_path(path):
	trees = get_trees(path)
	function_names = [f for f in flat(map(get_all_names, trees)) if not is_magic_name(f)]
	return flat(map(split_snake_case_name_to_words, function_names))


def get_top_verbs_in_path(path, top_size=10):
	trees = get_trees(path)
	functions = [f for f in flat(map(get_function_names_in_tree, trees)) if not is_magic_name(f)]
	print('Functions from files extracted\n')
	verbs = flat(map(get_verbs_from_function_name, functions))
	return collections.Counter(verbs).most_common(top_size)


def get_top_functions_names_in_path(path, top_size=10):
	trees = get_trees(path)
	nms = [f for f in flat(map(get_function_names_in_tree, trees)) if not is_magic_name(f)]
	return collections.Counter(nms).most_common(top_size)


parser = argparse.ArgumentParser(description='Word counter')
parser.add_argument('-g', help='Github project name')
parser.add_argument('-l', help='download from link')
parser.add_argument('-d', help='search in directory')
parser.add_argument('-o', help='Change output',
    choices=['cli', 'json', 'csv'], default='cli')
namespace = vars(parser.parse_args())


def get_path(namespace):
    if namespace['g']:
        print('Cloning git to directory ./repo')
        os.system('rm -rf ' + os.path.join('./', 'repo'))
        repo = Repo.clone_from(
            namespace['g'],
            os.path.join('./', 'repo'),
            branch='master'
        )
        print('--- DONE --- \n'
            + 'Path is ' + repo.working_tree_dir
        )
        return repo.working_tree_dir
    elif namespace['l']:
        print('Links support will be added in future releases.')
        print('Using default path.')
        return ''
    elif namespace['d']:
        print('Using directory ' + namespace['d'] + '/')
        return os.path.join(namespace['d'])
    else:
        print('Using default path ')
        return ''


if __name__ == '__main__':
	words = []
	projects = [
		'django',
		'flask',
		'pyramid',
		'reddit',
		'requests',
		'sqlalchemy',
	]

	path = get_path(namespace)
	if not path:
		for project in projects:
			path = os.path.join('.', project)
			print('\nSearching in %s directory' % path)
			words += get_top_verbs_in_path(path)
	else:
		print('Searching in %s directory' % path)
		words += get_top_verbs_in_path(path)


	top_size = 200
	print('=========================================')
	print('Total %s words, %s unique' % (len(words), len(set(words))))
	for word, occurence in collections.Counter(words).most_common(top_size):
		print(word, occurence)
