#!/usr/bin/env python
#
# Data Quality Checker also known as DQC
#
# Read the README.md for more detailed information
#
# Barcerlona Supercomputing Center - Centro Nacional de Supercomputacion
#        Earth Sciences Department - Computational Earth Sciences
#     
#     Authors: Ivan Jose Cernicharo Ortiz (ivan.cernicharo@bsc.es)
#             -
#             -
#

import sys
import logging
import os
import subprocess
import datetime

class standard_compliance_test:

    def __init__(self,path,type=None):
        self.type = type
        self.path = path
        self.files = self.dir_or_file()
#        print("Files or directory checked:")
        self.gridded_files = ''
        self.other_files = ''
        self.formats1 = ''
        self.formats2 = ''

    def dir_or_file(self):
        if os.path.isfile(self.path):
            print("Checking file")
            print(self.path)
            # do the file checking
            return [self.path]

        elif os.path.isdir(self.path):
            print("Found the following files to check ")
            # list all files in the folder
            list_files = self.list_files_folder()
            print(list_files)
            return list_files

    def list_files_folder(self):
        list_files = []
        if os.path.exists(self.path):
            if os.path.isfile(self.path) and self.path.endswith("grib") or self.path.endswith("nc") or self.path.endswith("grb"):
                list_files.append(self.path) 
            if os.path.isdir(self.path) or os.path.isfile(self.path):
                for root, dirs, files in os.walk(self.path):
                    print(files)
                    for f in files:
                        if f.endswith("grib") or f.endswith("nc") or f.endswith("grb"):
                            list_files.append(os.path.join(root,f))
            
                return sorted(list_files)

            else:
                raise Exception('\n\tGiven path is not a valid path\n')

    def run_cfchecker(self,item):
        """RUN CFCHECKER FOR ONE FILE
        """
        cmd0 = "cfchecks --version auto %s" %item

        p0 = subprocess.Popen(
            cmd0, shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT
            )

        out0, _ = p0.communicate()

        return out0

    def netcdf_test(self,args):
        """Check the CF COMPLIANCE FOR THE INPUT FILES
        """
        from subprocess import Popen

        for ncfile in args:

            string = '\nCF compliance test for file:\n'
            string += str(args) + '\n'

            out0 = self.run_cfchecker(ncfile)

            string = str(out0).replace('\'',"").replace("\"","").split('\\n')
            if any('ERROR:' in e for e in string):
                err = [item.split('ERROR:')[-1].strip() for item in string if item.startswith('ERROR:')]
                errstring = ncfile.split('/')[-1] + ' has ' + str(len(err))
                errstring += ' error messages' + '\n'
                errstring += '\n'.join(err)
                string += errstring
                logging.error(string)
            else:
                string += 'NO ERRORS FOUND when checking against CF'
                print('NO ERRORS FOUND when checking against CF')
                logging.info(string)
                pass
            # We are only interested on errors but could be interesting for 
            # further versions of the dqc_checker to analyze the warnings 
            # and info messages
            # wrn = [item.split('WARN:')[-1].strip() for item in string if item.startswith('WARN:')]
            # inf = [item.split('INFO:')[-1].strip() for item in string if item.startswith('INFO:')]

    def grib_test(self,args):
        """Check the GRIB BASELINE FOR THE INPUT FILES
        """
        import utils.grib_checker.grib_cck as gcck

        for gribfile in args:
            gcck.grib_cck_run(gribfile)

    def initiate_logging(self):
        # Initiate the logging
#        time0 = self.timefortitle
        path_logs = os.path.join(
            '/data',
            'DQC_LOGS'
        )

        if not os.path.exists(path_logs):
            os.makedirs(path_logs)

        default_log_name = '_'.join(
            [
                'LOG_TEST01_STANDARD_CHECK',
 #               (self.type).upper(),
 #               time0,
                '.log'
            ]
        )

        default_path = os.path.join(
            path_logs,
            default_log_name
        )
        
        logging.basicConfig(
            filename=default_path,
            format='%(levelname)s:%(asctime)s:%(message)s', 
            level=logging.INFO
        )

        stringA = '\n' + '#'*80 + '\n' + '#'*80
        stringA += '\n RUNNING STANDARD COMPLIANCE TEST FOR FOLDER:'
        stringA += '\n ' + self.path
        stringA += '\n AGAINST ' + (self.type).upper() + ' CONVENTION '
#        stringA += '\n EXECUTION TIME: ' + self.timeforinfo
        stringA += '\n' + '#'*80

        logging.info(stringA)

    def main(self):
        if self.type != None:

            if self.type == 'CF':
                ncfiles = [item for item in self.files if item.endswith('.nc')]
                if ncfiles != []:
                    self.initiate_logging()
                    self.netcdf_test(ncfiles)
                else:
                    raise Exception('No NetCDF files in the given input')
            else: 
                if self.type == 'grib':
                    gribfiles = [item for item in self.files if item.endswith('.grib')]
                    if gribfiles != []:
                        self.initiate_logging()
                        print("No CDM has been implemented yet for the variables to be checked - listing keys present in the files if grib2")
                        print(gribfiles)
                        self.grib_test(gribfiles)
                    else:
                        raise Exception('No GRIB files in the given input')
                else:
                    raise Exception('type not supported, type currently supported are grib and CF')
            

        else:
            print("No type selected, exiting")
            sys.exit()

if __name__ == "__main__":
    sys.exit()
