#!/usr/bin/python3

#	anti-cppcheck : utility for processing reports with static analysis
#	Copyright (C) 2019-2024 Alexey Appolonov
#
#	This program 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.
#
#	This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

import os
import shutil
import argparse
import anticppcheck.machinery as machinery
from anticppcheck.common import argparser
from anticppcheck.common import PrintExamples

aggr_report_path = ''

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Parsing the arguments

argparser.add_argument(
	'-s', '--stat', action='store_true',
	help='Printout an additional statistics')
args = argparser.parse_args()

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Usage examples

EXAMPLES = [(
	'Form a set of classified error/warning messages',
	'--path REPORT_FILE_NAME'
	),(
	'Form a set of classified error/warning messages and map '
	'the commentaries to that set',
	'--path REPORT_FILE_NAME --comments COMMENTS_FILE_NAME'
	),(
	'Form a set of classified error/warning messages and map the commentaries '
	'to that set and analyze the usage of the commentaries',
	'--path REPORT_FILE_NAME --comments COMMENTS_FILE_NAME --stat'
	)]

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

def Terminate(status=0):

	'''Perfrom some routines and then terminate'''

	if aggr_report_path:
		os.remove(aggr_report_path)
	exit(status)

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if __name__ == '__main__':

	# Printing the usage examples
	if args.examples:
		PrintExamples(__file__, EXAMPLES)
		exit(0)

	# Checking required arguments
	if any(not arg for arg in (args.type, args.analyzer, args.path)):
		argparser.error('--type, --analyzer, --path are required')

	# Checking given combinations of params
	if args.stat and not args.comments:
		argparser.error('--map and --stat require --comments')

	# If given path is a dir path then finding all reports in it's subdirs,
	#	concatenating found reports and analysing the whole thing altogether
	if os.path.isdir(args.path):
		report_paths = machinery.FindReports(args.path, args.analyzer)
		if report_paths:
			tmp_dir = os.path.join(os.path.expandvars('$TMP'))
			aggr_report_path = os.path.join(tmp_dir, 'anti-cppcheck')
			try:
				with open(aggr_report_path, 'wb') as outfile:
					for report_path in report_paths:
						with open(report_path, 'rb') as infile:
							shutil.copyfileobj(infile, outfile)
			except Exception as e:
				print('Error: ' + str(e))
				Terminate(1)
		args.path = aggr_report_path

	# Creating the machine that instantly parses a given report file
	#	and a given comments file and holds the data for later request
	try:
		machine = machinery.Machine(args.type,
			args.analyzer,
			args.path,
			args.comments)
	except Exception as e:
		print('Error: ' + str(e))
		Terminate(1)

	# Printing % of var types of msg presented in the report and, if comments
	#	filepath have been passed, mapping those comments to that messages
	machine.PercOfVarTypesOfMsg(args.path)

	# Analyzing a completeness of the comments as well as some other stuff
	if args.stat:
		machine.Stat(args.path)

	Terminate()
