#! /usr/bin/env python3
# -*- coding: utf-8 -*-

#	Copyright 2013-2014, Marten de Vries
#
#	This file is part of OpenTeacher.
#
#	OpenTeacher is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#
#	OpenTeacher is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with OpenTeacher.  If not, see <http://www.gnu.org/licenses/>.

import subprocess
import os
import collections
import re
import sys

ComplexityResult = collections.namedtuple("ComplexityResult", "position complexity")

def pythonPaths(basePath):
	for root, dir, files in os.walk(basePath):
		for file in files:
			isNotAPythonFile = not file.endswith(".py")
			shouldNotBeChecked = (
				isNotAPythonFile or
				"pyinstaller" in root or
				"admin_files" in root or
				"pyttsx" in root or
				"latexcodec" in root or
				"collectionscompat.py" in file or
				"pyratemp" in file
			)
			if shouldNotBeChecked:
				continue
			yield os.path.join(root, file)

def complexityInfo(output):
	for line in output.split("\n"):
		if not line:
			continue
		data = line.rsplit(' ', 1)
		data[1] = int(data[1])
		result = ComplexityResult._make(data)
		#either functions that wrap other functions until the context
		#is ready (e.g. used for lazy loading flask & PyQt5), or
		#functions from other sources.
		if not re.search(r"install.*Classes|initialize.*|crossdomain", result.position):
			yield result

def complexityForPaths(basePath):
	for path in pythonPaths(basePath):
		output = subprocess.check_output([sys.executable, "-m", "mccabe", "--min=8", path]).decode('UTF-8').strip()
		info = list(complexityInfo(output))
		if info:
			yield path, info

def main(basePath):
	def highestComplexity(pathAndResults):
		return max(r.complexity for r in pathAndResults[1])

	for path, results in reversed(sorted(complexityForPaths(basePath), key=highestComplexity)):
		print(path)
		for result in reversed(sorted(results, key=lambda r: r.complexity)):
			print("Complexity:", result.complexity, "Position:", result.position)
		print("")
