#!/usr/bin/python3

#	alt-tasks-explorer : A set of utils used on top of the "alt-tasks" utility
#	Copyright (C) 2023 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 argparse
import os
import re
from alt_tasks_explorer.status import Warn, FatalError

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

argparser = argparse.ArgumentParser()
argparser.add_argument(
	'--subtasks_list',
	metavar='FILE_PATH', type=str, required=True,
	help='Path of a file containing subtasks info'
	)
argparser.add_argument(
	'-o', '--out_dir',
	metavar='DIR_PATH', type=str, required=True,
	help='Path to the directory where the output files will be saved'
	)
args = argparser.parse_args()

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

def ReadSubstaskList(file_path):

	'''Write a content of a specified file to a list; Each element of
	a resulting list is a list of length 4; Each line of the file should have
	a following format: <task_id> <subtask_id> <branch> <package>'''

	subtasks_info = []

	try:
		with open(file_path, 'r') as f:
			for n, line in enumerate(f):
				cols = line.split()
				if len(cols) != 4:
					FatalError('Wrong format of the input data, '
						f'see "{file_path}", line {n}')
				subtasks_info.append(cols)
	except Exception:
		FatalError(f'Can\'t read a list of subtasks "{file_path}"')

	return subtasks_info

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

if __name__ == '__main__' :

	count_logs = 0
	count_checks = 0
	missing_logs = []
	missing_checks = []

	try:
		if not os.path.exists(args.out_dir):
			os.makedirs(args.out_dir)
	except PermissionError:
		FatalError(f'Can\'t create the output dir "{args.out_dir}"')

	tasks_archive_dir = '/tasks/archive/done'
	if not os.path.exists(tasks_archive_dir):
		FatalError(f'Dir "{tasks_archive_dir}" does not exist')

	for subtask_info in ReadSubstaskList(args.subtasks_list):

		task_id, subtask_id, branch, package = subtask_info
		cluster_id  = str(int(task_id) // 1024)
		task_dir    = f'{tasks_archive_dir}/_{cluster_id}/{task_id}'
		subtask_dir = f'{task_dir}/build/{subtask_id}'
		log_path    = f'{subtask_dir}/x86_64/log'

		if os.path.exists(log_path):
			count_logs += 1
		else:
			missing_logs.append(log_path)
			continue

		check_txt = ''

		try:
			with open(log_path, 'r') as f:
				for n, line in enumerate(f):
					if 'Executing(%check):' in line:
						if check_txt:
							check_txt = ''
							Warn(f'Second %check in a same log: {log_path}')
							break
						check_txt += line
					elif re.search(r'Executing(\([^\s]+\))?:', line):
						if check_txt:
							break
					elif check_txt:
						check_txt += line
		except Exception as exc:
			Warn(f'{log_path}: {str(exc)}')

		if not check_txt:
			missing_checks.append(log_path)
			continue
		else:
			count_checks += 1

		out_filename = f'{package}-{branch}-{task_id}-{subtask_id}.check.log'
		out_filepath = os.path.join(args.out_dir, out_filename)

		try:
			with open(out_filepath, "w") as f:
				f.write(check_txt)
		except FileNotFoundError:
			FatalError(f'Output dir "{args.out_path}" does not exist')
		except PermissionError:
			FatalError('No permission to write to the output dir '
				f'"{args.out_path}"')
		except Exceptopn as exc:
			FatalError(str(exc))

	print(f'Number of correctly processed log files:\n\t{count_logs}')

	if count_logs:
		print(f'Number of %check found in those files:\n\t{count_checks}')

	if missing_logs:
		print('Missing log files:')
		for path in missing_logs:
			print(f'\t{path}')

	if missing_checks:
		print('Log files that does not contain %check:')
		for path in missing_checks:
			print(f'\t{path}')

	exit(0)
