#!/usr/bin/python3
#
# Univention Debug
#  view debug log files
#
# Copyright 2004-2021 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.

from __future__ import print_function

import sys
import getopt
import re

only = False
include_modules = []
exclude_modules = []
functions = []
regexps = []
breakline = 0

opts, args = getopt.getopt(sys.argv[1:], 'f:m:r:l:b:n')
for opt, val in opts:
	if opt == '-f':
		if val[-1] == '-':
			functions.append((val[:-1], 0))
		elif val[-1] == '+':
			functions.append((val[:-1], 2))
		else:
			functions.append((val, 1))
	elif opt == '-m':
		if val[-1] == '-':
			exclude_modules.append(val[:-1])
		else:
			include_modules.append(val)
	elif opt == '-r':
		regexps.append(re.compile(val))
	elif opt == '-b':
		breakline = int(val)
	elif opt == '-n':
		only = True

# level
skip = True
levels = ['^']
msg_pattern = re.compile(r'^([^ ]+) *\( ([^ ]+) +\) : (.+)$')


def suspended(levels):
	suspend = 1
	priority = 0
	for pattern, type in functions:
		for level in levels:
			if type != 1 and re.match(pattern, level):
				suspend = type
		priority += 1

	return suspend < 1


def spacing(depth):
	if depth == 0:
		return ''
	else:
		return '   ' * depth


def split(line, l):
	if len(line) < l:
		return [line]
	res = []
	ls = len(line) / l
	for i in range(0, ls + 1):
		n = line[i * l:(i + 1) * l]
		if not n:
			break
		res.append(n)
	return res


while True:
	line = sys.stdin.readline()
	if line == '':
		break
	line = line[0:-1]
	if line.startswith('DEBUG_INIT'):
		if not breakline:
			print('-' * 80)
		else:
			print('-' * breakline)
		skip = False
	elif skip:
		pass
	elif line.startswith('UNIVENTION_DEBUG_BEGIN  : '):
		function = line[line.find(':') + 2:]
		levels.append(function)

		if not suspended(levels):
			if breakline:
				s = spacing(len(levels) - 1)
				sl = breakline - len(s) - 3
				c = 1
				for i in split(function, sl):
					if c:
						print(s, '+', i)
						c = 0
					else:
						print(s, ' ', i)
			else:
				print(spacing(len(levels) - 1), '+', function)

	elif line.startswith('UNIVENTION_DEBUG_END    : '):
		function = line[line.find(':') + 2:]
		levels.pop()

	else:
		if not suspended(levels):
			# ADMIN       ( INFO    ) : writing XML
			msgs = msg_pattern.findall(line)
			if msgs:
				module, level, msg = msgs[0]
				if regexps:
					for regexp in regexps:
						if not regexp.match(msg):
							continue
				print(spacing(len(levels)), msg)
