#!/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 re
import glob
import logging
import tempfile
import shutil
from contextlib import contextmanager
from datetime import date, datetime


"""
Check a parameter inside the config file (based on ConfigParser)
"""
def check_param_config(config, section, parameter):
    try:
        return config[section][parameter]         
    except:        
        raise Exception('Parameter {p} not defined. Check configuration file section [{s}]'.format(s=section, p=parameter))
        return None

def check_opt_param_config(config, section, parameter, default=''):
    try:
        return config[section][parameter]         
    except:                
        return default

"""
Returns a temporary dir that cleans up on exit (for unzipping)
"""
@contextmanager
def tempdir():
    path = tempfile.mkdtemp()    
    try:
        yield path
    finally:
        try:
            shutil.rmtree(path)
        except IOError:
            raise Exception('Failed to clean up temp dir {}'.format(path))   

"""
Return file list matching a given pattern
"""
def dir_or_file(abspath, pattern):
    if os.path.isfile(abspath):
        print("INFO: Checking file")
        print(abspath)
        # do the file checking
        return [abspath]

    elif os.path.isdir(abspath):        
        # Empty pattern equals all files
        if pattern.rstrip() == "":
            pattern = '*'

        # list all files in the folder
        list_files = glob.glob(os.path.join(abspath, pattern))
        print("INFO: Path {}".format(abspath))
        print("INFO: Found {} files to check".format(len(list_files)))
        
        if len(list_files):
            print("INFO: [1]: {}".format(os.path.basename(list_files[0])))
            print("INFO: [N]: {}\n".format(os.path.basename(list_files[-1])))
        else:
            raise Exception('No files found for analysis')

        # Logging files to analyze
        basenames = []
        for f in list_files:
            basenames.append(os.path.basename(f))
        logging.info('Checking {}'.format(basenames))

        return list_files            

"""
Create logging associated to a test [00-0X]
"""       
def initiate_logging(path_logs, path_files, testid):

    # Directory check
    if not os.path.exists(path_logs):
        os.makedirs(path_logs)

    # Log file name
    default_log_name = '_'.join(
        [
            'LOG',
            testid,
            date.today().strftime('%Y%m%d'),
            '.txt'
        ]
    )
    default_path = os.path.join(path_logs, default_log_name)
    print('INFO: Saving log in {}'.format(default_path))
    
    # Logging configuration
    logging.basicConfig(
        filename=default_path,
        format='%(name)s:%(levelname)s:%(asctime)s:%(message)s', 
        level=logging.INFO,
        filemode = 'w'
    )

    # Write header
    stringA =  '\n' + '#'*80 + '\n'
    stringA += '\n RUNNING TEST {}'.format(testid)
    stringA += '\n DIR = ' + path_files + '\n'
    stringA += '\n' + '#'*80
    logging.info(stringA)

    return default_path


"""
Write a result of a check
"""
def save_result(config, res_dir, fname):

    # Directory check
    if not os.path.exists(res_dir):
        os.makedirs(res_dir)

    # Save result
    out_file = os.path.join(res_dir, fname)
    print('INFO: Saving result to {}'.format(out_file))
    with open(out_file, 'w') as configfile:
        # Result
        config.write(configfile)

    return out_file

"""
Progress bar function
"""
def print_progress(iteration, total, prefix='', suffix='', decimals=1, length=80, fill='#', printEnd="\r"):

    # Call in a loop
    percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
    filledLength = int(length * iteration // total)
    bar = fill * filledLength + '-' * (length - filledLength)
    print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end = printEnd)
    
    # Print New Line on Complete
    if iteration == total: 
        print('\n')


"""
Get start and end time given a list of files
"""
def get_t0_tn(file_list):

    dates = []
    for f in file_list:
        pt = re.search("([0-9]{8})", f) # YYYYMMDD
        try:
            dates.append(datetime.strptime(pt[0], '%Y%m%d'))
        except:
            raise Exception('Invalid date format. Please name files accordingly: YYYYMMDD')

    # Sort dates
    s=sorted(dates)

    # First date and Last date
    return s[0].replace(hour=0, minute=0, second=0), s[-1].replace(hour=23, minute=59, second=59)