#!/usr/bin/env python
#
# Data Quality Checker also known as DQC
#
# Read the README.md for more detailed information
#
#       Barcelona Supercomputing Center - Centro Nacional de Supercomputacion
#       Earth Sciences Department - Computational Earth Sciences
#     
#     Authors: 
#       Joan Sala Calero (joan.sala@bsc.es)

import os

import configparser
from io import StringIO
from datetime import date

from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch, cm
from reportlab.pdfbase.pdfmetrics import registerFont

# Header and footer (official C3S)
imgdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'img')

# Register official C3S font
fontdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'font')
registerFont(TTFont('Calibri', os.path.join(fontdir, 'Calibri.ttf')))

"""
Convert a txt to a pdf file (reporting)
"""
def save_txt_report(txt_file, pdf_file):

	# PDF report name
	print('INFO: Saving report to {}'.format(pdf_file))

	# Read content (detailed txt file messages)
	with open(txt_file, 'r') as f:
		txt_str = f.read()

	# Write PDF
	try:
		# Init
		c = canvas.Canvas(pdf_file)
		break_into_pages(txt_str, c, 80, 'Detailed log output', True)
		# Save
		c.save()
	except:
		raise Exception('Could not convert txt to pdf. Check directory permissions')

"""
Convert a ini to a pdf file (reporting)
"""
def save_pdf_report(testname, res_file, log_file):

	# PDF report name
	pdf_file = res_file.replace('.ini', '-{}.pdf'.format(testname))
	print('INFO: Saving report to {}'.format(pdf_file))

	# Read+Filter content (result/config)
	res_str = filter_config(res_file, testname)

	# Read content (detailed log file messages)
	log_str = ''
	with open(log_file, 'r') as f2:
		log_str = f2.read()
		log_str = filter_page(testname, log_str)

	# Write PDF
	try:
		# Init		
		c = canvas.Canvas(pdf_file)
		
		# Write 2 sections	
		break_into_pages(res_str, c, 80, '1. Summary of data checks', False)
		break_into_pages(log_str, c, 80, '2. Detailed log output', True)
		
		# Save
		c.save()		
	except:
		raise Exception('Could not convert ini to pdf. Check directory permissions')

	return pdf_file

"""
Filter a config object
"""
def filter_config(res_file, testname):
	cf = configparser.ConfigParser()
	cf.read(res_file)

	for s in cf.sections():
		# Remove log (unnecessary for CMS)
		if 'log' in cf[s]:
			cf[s].pop('log')

		# Remove section (if not relevant for testXX)
		if not(testname in s):
			cf.remove_section(s)
	
	res_str = StringIO()		
	cf.write(res_str)
	return res_str.getvalue()	

"""
Filter page (by test name)
"""
def filter_page(s, page_str):
	out_str = ''
	s1 = s.replace('-', '_')
	s2 = s.replace('_', '-')

	for l in page_str.splitlines():	
		iden = l.split(':')[0]

		if 'not implemented yet' in l:
			continue

		if s1 in iden or s2 in iden or s in iden:
			out_str += (l + '\n')
	return out_str


"""
Init PDF page (body)
"""
def init_page(c, font_size=6):

	# Normal text prepare
	t = c.beginText()
	t.setFillColorRGB(0, 0, 0)
	t.setFont('Calibri', font_size)
	t.setCharSpace(0.5)
	t.setTextOrigin(40, 700)
	return t

"""
Init PDF page (title)
"""
def init_title(c, font_size=9):

	# TITLE text prepare - #941333
	t = c.beginText()
	t.setFillColorRGB(0.58, 0.075, 0.2)
	t.setFont('Calibri', font_size)
	t.setCharSpace(0.5)
	t.setTextOrigin(40, 725)
	return t

"""
Write PDF page
"""
def write_page(c, body, title, title_str):

	# Header
	c.drawInlineImage(os.path.join(imgdir, "header.png"), 0, 755, height=1.2*inch, width=8.5*inch)

	# Text (title + body)
	title.textLine(title_str)
	c.drawText(title)
	c.drawText(body)

	# Footer
	c.drawImage(os.path.join(imgdir, "footer.png"), 0, 0, mask='auto', height=1.7*inch, width=8.5*inch)

	# Finalize
	c.showPage()

	return init_title(c), init_page(c)

"""
Get page title/section
"""
def get_page_title(log_page, tit, page_count):

	if log_page:
		return tit + ' (page {})'.format(page_count)
	else:
		return tit + ' (generated on {})'.format(date.today())

"""
Write a string into pages
"""
def break_into_pages(txtstr, c, lines_per_page, tit, log_page):

	title = init_title(c)
	body = init_page(c)
	count_lines = 0
	page_count = 1

	for l in txtstr.split('\n'):
		body.textLine(l)
		if count_lines == lines_per_page:
			title, body = write_page(c, body, title, get_page_title(log_page, tit, page_count))
			count_lines = 0
			page_count += 1
		else:
			count_lines+=1

	# Last page
	if count_lines != 0:
		write_page(c, body, title, get_page_title(log_page, tit, page_count))

