#!/usr/bin/env python
"""
cf_checks.py
 Python script to run the cf-checker from the command line
 Only requires:
  1  location of area-type-table.xml
  2  location of standard-name-table.xml
  3  python netCDF4 module to be installed
  4  LD_LIBRARY_PATH to be set in local ENV *before* running script, i.e.:
 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/usr/local/apps/udunits/2.1.21/LP64/lib"
  5 path of data directory 
  6 glob pattern to match

 Input : Configuration file  cf_checks.cfg (in same directory as script)
 Output: cf check output/err results to stdout
 to run: python cf_checks.py -c cf_checks.cfg

"""

import os
import glob
import subprocess
import getopt
import sys
from netCDF4 import Dataset

def check_standard_names(filename):
    """
    Function to test if the NetCDF variables actually have standard names set.
    The values given to these will be checked in the run_cf_checks function
    """
    print "**********************\n"
    print "File: %s" % filename
    print "Check for standard_name attribute attached to variables"
    print "\n**********************"
    fin = Dataset(filename,"r")
    var_list = []
    std_name_count = 0
    data_check = 0
    for v_name, varin in fin.variables.iteritems():
        var_list.append(str(v_name))
        if "standard_name" in varin.ncattrs():
            print v_name, " variable -OK: has standard_name attribute set"
            std_name_count = std_name_count +1
            if v_name == "data":
                data_check = 1
        else:
            print v_name, " variable -ERROR: has NO standard_name attribute set"
    fin.close()
    print "**********************\n"
    print "Summary for %s :\n" % filename
    print "%d of %d variables have standard_name attribute set" % \
    (std_name_count,len(var_list))
    if data_check == 0 :
        print "ERROR: 'data' variable has NO standard_name attribute" 
    print "\n**********************"

def run_cf_checks(flist_in, cf_cmd):
    """
    check that variables have standard_name attributes and then
    run actual CF checks using the local version of the CF checker on the
    filelist created by the glob command
    """
    for fname in flist_in:
        check_standard_names(fname)
        print cf_cmd+fname
        process_out = subprocess.Popen(cf_cmd+fname, shell=True, \
        stdout=subprocess.PIPE)
        output, err = process_out.communicate()
        print "*** Running  CF checks command ***\n"
        if err:
            
            print "Error in running checks :", err

        for line in output.splitlines():
            print line
            if "CHECKING NetCDF FILE:" in line:
                print line

def main():
    """
    Set up the input file paths and environment ariables to allow the
    CF checker to run from the command line

    These are held by objects containing :
         hardcoded path to data directory
         glob pattern to generate list of files
         path to cfcheck script, 
         path to local copy of area type table,
         path to local copy of standard name table,
         CF version to check against
    """
    options, remainder = getopt.getopt(sys.argv[1:],'c:')
    print options,remainder
    if len(options) ==0:
        print "Option required; Exiting"
        sys.exit()
    for opt, arg in options:
        print opt,arg
        if opt in ('-c'):
           cf_cfg_fname = arg
           print "Config file is ",cf_cfg_fname
        else:
            print "Config file required; Exiting"
            sys.exit()
    cfg_file=open(cf_cfg_fname,"r")
    lines=cfg_file.readlines()
    for line in lines:
#        print line
        if line.startswith("#"): # comment line: 
            continue
        elif line.startswith("\'"): # "Env: " line
            option, value = line.split("=")
            o=option.strip()
            v=value.strip()
            os.environ[o] ="$"+o+":"+v            
        else:
            print line
            option, value = line.split("=")
            o=option.strip()
            v=value.strip()
            if o == "data_dir":
               print "data Dir match"
               data_dir=v
               print data_dir
            elif o == "glob_pattern":
                glob_pattern=v
            elif o == "path_to_cfchecks":
                path_to_cfchecks=v
            elif o == "path_to_area_table":
                 path_to_area_table = v
            elif o == "path_to_standard_name_table":
                 path_to_standard_name_table = v
            elif o == "cf_version":
                cf_version = v
            else:
                print "Unmatched option"
    cfg_file.close()

    print data_dir, glob_pattern
    full_glob=data_dir + glob_pattern
    print full_glob
    flist = glob.glob(data_dir + glob_pattern)
    print "files to CF check are: \n", flist
    print path_to_cfchecks,path_to_area_table,path_to_standard_name_table
    print cf_version
    cf_cmd_root = path_to_cfchecks+" -a " + path_to_area_table + " -s " +\
                  path_to_standard_name_table+" -v "+cf_version+" "
    print cf_cmd_root
    run_cf_checks(flist, cf_cmd_root)

if __name__ == "__main__":
    main()


