#!/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 os
import sys
import argparse
from collections import defaultdict
from subprocess  import run  as run_subprocess
from alt_tasks_explorer.status import Done, Warn, FatalError
from alt_tasks_explorer.fileop import WriteTmpFile, RemoveTmpFile

WORK_DIR    = os.path.dirname(os.path.abspath(sys.argv[0]))
M_PREFIX    = 'alt-tasks-'
M_CHECKLOGS = 'checklogs'
MODULES     = [M_CHECKLOGS]

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

argparser = argparse.ArgumentParser()
argparser.add_argument(
	'--alt_tasks_util',
	metavar='SHELL_CMD_OR_FILE_PATH', type=str, default='alt-tasks',
	help='How to call the "alt-tasks" utility ("alt-tasks" by default)'
	)
argparser.add_argument(
	'--src_list',
	metavar='SRC_LIST_FILE_PATH', type=str, required=True,
	help='Path of a file containing full names of src packages to be processed'
	)
argparser.add_argument(
	'-p', '--process',
	metavar='MODULE_TO_RUN_OVER_FOUND_TASKS', type=str, required=True,
	choices=MODULES,
	help=f'Choose from {", ".join(MODULES)}' if len(MODULES) > 1 else \
	f'There is only one module now: {MODULES[0]}'
	)
argparser.add_argument(
	'-o', '--out_dir',
	metavar='DIR_PATH', type=str,
	help='Path to the directory where the output files will be saved'
	)
args = argparser.parse_args()

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

class SubTask():

	'''Primitive class used to hold subtask info together'''

	def __init__(self, branch, package):

		self.branch  = branch
		self.package = package

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

def Run(cmd, capture_output=False):

	'''Run passed command, display its status, capture output if requested'''

	cmd_str = ' '.join([f'"{el}"' if ' ' in el else el for el in cmd])

	print(f'Running "{cmd_str}"...', flush=True)

	try:
		completed_process = run_subprocess(cmd, capture_output=capture_output)
	except Exception as exc:
		FatalError(str(exc))

	if not completed_process or completed_process.returncode != 0:
		if completed_process:
			if capture_output:
				stdout = completed_process.stdout
				if stdout:
					print(stdout.strip().decode('utf-8'))
			errcode = completed_process.returncode
			msg = f'The command terminated with error code {errcode}'
		else:
			msg = 'The process cannot be completed properly'
		FatalError(msg)

	Done()

	return completed_process

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

if __name__ == '__main__' :

	# Run alt-tasks

	cmd = [args.alt_tasks_util, '--src_name', args.src_list,
		'--format', '%t %s %b %n %v', '--no_prev_ver']

	completed_process = Run(cmd, capture_output=True)

	builds = defaultdict(dict)

	for line in completed_process.stdout.splitlines():

		if not line:
			continue

		try:
			ret = [el.decode('utf-8') for el in line.strip().split()]
			task_id, subtask_id, branch, name, ver_rel = ret
		except ValueError:
			FatalError('A different output format is expected; Can\'t parse '
				f'this line: {line}')
		except Exception as exc:
			FatalError(str(exc))

		builds[task_id][subtask_id] = SubTask(branch, f'{name}-{ver_rel}')

	tmp_file_path = ''

	# Use a full path to run specified process
	cmd = [os.path.join(WORK_DIR, f'{M_PREFIX}{args.process}')]

	if args.process == M_CHECKLOGS:

		# Write info about searched subtasks to a tmp file

		entries = [f'{task_id} {subtask_id} {subtask.branch} {subtask.package}'
			for task_id, subtasks in builds.items()
				for subtask_id, subtask in subtasks.items()]

		tmp_file_path = WriteTmpFile(entries)

		# Run alt-tasks-checklogs

		cmd += ['--subtasks_list', tmp_file_path]
		if args.out_dir:
			cmd += ['--out_dir', args.out_dir]

	else:
		exit(1)

	# Run the specified process, and then perform the cleanup
	Run(cmd)
	RemoveTmpFile(tmp_file_path)

	exit(0)
