#!/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)
#       Daniel Trujillo Viedma (daniel.trujillo@bsc.es)
#

import json
import sys
import dateutil.parser
from _functools import reduce

if len(sys.argv) != 4:
    print('usage: python json2txt_integration.py <input JSON> <section1.txt> <section2.txt>')
    sys.exit()

with open(sys.argv[1], 'r') as f:
    input_read = f.read()

json_parsed = json.loads(input_read)

# Extract preliminary data
tests_data = json_parsed["results"]
tool_name = json_parsed["info"]["tool_name"]
test_timestamp = dateutil.parser.isoparse(json_parsed["info"]["check_run_time"]).strftime('%d/%m/%Y')

# First, build the summary information
passed_test = lambda result: result["output"]["passed"] == True
number_of_tests_passed = len(list(filter(passed_test, tests_data)))
percentage_passed = 100 * number_of_tests_passed / len(tests_data)

results = "res = {}% passed, {}% not passed".format(percentage_passed, (100-percentage_passed))
message = "msg = The tool " + tool_name + (" has " if (percentage_passed == 100) else " hasn't ") + "passed all integration tests"
number_of_tests = "number of tests = {}".format(len(tests_data))
generation_time = "Generated on " + test_timestamp

get_dataset_name = lambda result: result["input"][0]
dataset_names = map(get_dataset_name, tests_data)
get_dataset_type = lambda dataset_name: dataset_name[0:dataset_name.find("-")]
dataset_types = list(set(map(get_dataset_type, dataset_names)))
dataset_types_message = "dataset types considered = " + reduce(lambda msg,new_type: "{}, {}".format(msg, new_type), dataset_types[1:], dataset_types[0])


# Now extract relevant data for the report    
def dictToString(obj):
    return reduce(lambda a,b : "{}\n  {}: {}".format(a, b[0],b[1]), obj.items(), "")

extract_data = lambda result: "**  Integration test number {}  **\nPassed: {}\nInput: {}\nParameters applied:{}\nResults:{}\n \n \n \n".format(result[1], result[0]["output"]["passed"], result[0]["input"][0], dictToString(result[0]["input"][1]), dictToString(result[0]["output"]["result"][0]))

# So, this has to be inside a list() because in the next section we use 2 times
# relevant_data and, although iterators are lazy, they are also mutable, so the first
# following map would consume the iterator, leaving none for the second map.
def zipWithIndex(array):
    return list(zip(array, range(0, len(array))))

relevant_data = list(map(extract_data, zipWithIndex(tests_data)))

# The final step is to format the relevant data
format_log  = lambda data: "{}\n\n".format(data)
     
relevant_data_formatted = "{}\n{}\n{}\n{}\n{}".format(results, message, number_of_tests, dataset_types_message, generation_time)
relevant_log_formatted  = relevant_data

# And write the files
with open(sys.argv[2], 'w') as f:
    list(map(lambda s: f.write(s), relevant_data_formatted))

with open(sys.argv[3], 'w') as f:
    list(map(lambda s: f.write(s), relevant_log_formatted))




