#!/usr/bin/env python

from lxml import etree
import zipfile
from datetime import date, time, datetime, timedelta
from time import strftime
import calendar
import re
import sys

#NOTE this is an executable file (set permissions accordingly)

#NOTE when used in hadoop specify correct path for 'zipf'
#zipf = zipfile.ZipFile("../%s/%s_%s.zip" % (yy, station, yy))
#zipf = zipfile.ZipFile("/user/hduser/data-met/%s/%s_%s.zip" % (yy, station, yy))

#based on /home/javlacalle/Documents/explore/data-met/compare-max-min-periods/merge.py

#echo "G049;2003;2009;1;2003,2004,2005,2006,2007,2008,2009" | ./mapper.py | sort -k1,3
#echo "G049;2003;2009;1;2003,2004,2005,2006,2007,2008,2009" | ./mapper.py | sort -k1,3 | ./reducer.py
#cat summary.txt | ./mapper.py | sort -k1,3 | ./reducer.py

#NOTE multiple keys, see
#http://hadoop.apache.org/docs/r0.19.1/streaming.html
#-D mapred.text.key.partitioner.options=-k1,2

#NOTE do not use print for debugging or track the computations
#since it would be passed to the reducer,
#comment out all the print lines except
#print "%s\t%s\t%s\t%s" % (station, yy, imonth, temp)

#missing values (NAs) are defined as '-', not simply '' or ' '
#because in those cases the field is missing when splitting the string
#and tmp[3] gives an error

##FIXME see for line in iter(sys.stdin.readline, ""): 
##FIXME see using iterators
#file:///home/javlacalle/Documents/explore/hadoop/
#Writing%20An%20Hadoop%20MapReduce%20Program%20In%20Python%20-%20Michael%20G.%20Noll.html

#FIXME rename 'yy' as 'year'

def fillYearNA (station, yy):
  """
  in the mapper we don't really need to fill with NAs ('-')
  all the days and times in the year, we only look for the 
  maximum so if the data for a year are missing then monthly 
  maximum values will be missing as well and there is no need 
  to check day by day that the value is missing;
  in the file merge.py we fill a year or a period with NAs ('-')
  in order to get a regular series with data every 10 minutes
  """
  for imonth in range(1, 13):
    print "%s\t%s\t%s\t%s" % (station, yy, imonth, '-')

def getAirTempVarName (tree):
  #NOTE check if the variable related to air temperature is always unique (one altitude)
  #NOTE check that all the same set of variable names is used in a single xml file
  #print xmlData.findall("//dia/hora/Meteoros")[0][0].tag
  #varNames = [e.tag for e in xmlData.find("//dia/hora/Meteoros")]
  #print varNames
  """
  get the name of the variable related to air temperature (Tem.Aire), if any,
  altitude is include in the name and, hence, names may vary across files;
  the variable 'Temp.Aire' is unique, there are multiple entries 
  for 'TemTer' but this is not considered;
  it is assumed that all the day-hour-items within a xml file 
  contain the same number of variables with the same names
  """
  varTemAire = [e.tag for e in tree.find("//dia/hora/Meteoros") 
    if re.search(r'^Tem\.Aire.*', e.tag)]
  #print len(varTemAire)
  if len(varTemAire) == 0:
    return '-'
  elif len(varTemAire) > 1: # debug
    #if this happens check which one was fetched and decide a general rule
    #print "More than one item with name r'^Temp\.Aire.*' were found"
    pass
  #if len(varTemAire) == 0: #then fill with ''
  #print varTemAire
  else:
    return varTemAire[0]

#

#fsum = open('summary.txt', 'r')

# main loop

#print strftime("%Y-%m-%d %H:%M:%S")

#echo"G049;2003;2009;1;2003,2004,2005,2006,2007,2008,2009"

for line in sys.stdin:
  #print line[:-1].split(";")
  tmp = line.split(";")
  station, y0, yN = tmp[0], int(tmp[1]), int(tmp[2])
  #
  #break
  #  
  #print station  
  #fout = open('../csv-temperature/%s.csv' % station, 'w')
  
  for yy in range(y0, yN + 1):
    #print yy
    for imonth in range(1, 13):
      try:
        zipf = zipfile.ZipFile("../%s/%s_%s.zip" % (yy, station, yy))
        #zipf = zipfile.ZipFile("/user/hduser/data-met/%s/%s_%s.zip" % (yy, station, yy))
      except IOError:        
        fillYearNA(station, yy)
        #print "missing %s" % yy
        #use 'break' not 'continue' since the all the months in the year,
        #i.e. the whole 'for imonth' loop is skipped, not only one month
        break
      #zipf.namelist()
      #xmlf = zipf.open("%s/%s_%s_%s.xml" % (station, station, yy, imonth))
      isNA = False
      try:     
        xmlf = zipf.open("%s/%s_%s_%s.xml" % (station, station, yy, imonth))
      except KeyError:
        try: # first try if month '1' is denoted '01'
          xmlf = zipf.open("%s/%s_%s_0%s.xml" % (station, station, yy, imonth))
        except KeyError: # the file does not exist (missing values)
	  isNA = True
	  #temp = ''    
      if isNA == False: # if file exists
        xmlData = etree.parse(xmlf)
        monthDays = xmlData.findall("//dia")
        #print len(monthDays)
        # get the name of the variable related to air temperature
        AirTempVarName = getAirTempVarName(xmlData)
        if AirTempVarName != '-':
          for day in monthDays:
            dayLabel = day.attrib['Dia']
	    hours = day.findall("hora")
	    for hour in hours:
              #temp = hour.findtext("Meteoros/Tem.Aire._a_620cm")
              temp = hour.findtext("Meteoros/%s" % AirTempVarName)
              if temp == '' or temp == None:
		temp = '-'
	      #print "%s; %s; %s" % (dayLabel, hour.attrib['Hora'], temp)
	      #fout.write("%s;%s;%s\n" % (dayLabel, hour.attrib['Hora'], temp))
	      print "%s\t%s\t%s\t%s" % (station, yy, imonth, temp)
          xmlf.close()
        else: # if variable r'^Tem\.Aire.*' does not exist
          print "%s\t%s\t%s\t%s" % (station, yy, imonth, '-')
      else: # if file does not exist (missing data for current year and month)
        print "%s\t%s\t%s\t%s" % (station, yy, imonth, '-')
      zipf.close()
  #fout.close()

#fsum.close()

#print strftime("%Y-%m-%d %H:%M:%S")
