#!/usr/bin/python

import sys,time,os,traceback
import fandango as fun
import PyTangoArchiving

sep = '\t'
linesep = '\n'
arrsep = ', '
print arrsep*80

try:
  attrs = [a for a in sys.argv[1:] if not a.startswith('-')] #sys.argv[1:-3]
  args = [a for a in sys.argv[1:] if a.startswith('-')]
  if not any(fun.inCl(s,args) for s in ('--modes','--config')):
    assert len(sys.argv)>=5, 'na'
    start,stop = attrs[-3:-1]
    filename = attrs[-1]
    attrs = map(str.lower,attrs[:-3])
    assert fun.str2time(start)>0,'wrong start'
    assert fun.str2time(stop)>0,'wrong stop'
    [a.split('/')[2] for a in attrs]
  else:
    if len(sys.argv)==3: filename = sys.argv[-1]
    else: filename = '/tmp/%s_archiving_modes_%s.csv'%(os.environ['HOST'],fun.time2str(cad='%Y%m%d-%H%M%S'))
except:
  print traceback.format_exc()
  print '\nWrong arguments, right syntax is:\n\tarchiving2csv [--resolution=X(s)] [--hdb] [--tdb] [--modes] ["--arrsep=,"][attributes] ["Y-m-d H:M"] ["Y-m-d H:M"] filename.csv\n\n'
  print '--hdb/tdb : choose database'
  print '--modes : export modes instead of values'
  print '--config : same, in "human format"'
  print '--arrsep/--no-sep : default separator between arrays values'
  print '--sep : separator between columns'
  print '--linesep : character between lines'
  print '--resolution : force periodicity of values to a fix period'  
  print '--noheader : do not include headers'
  print '--nodate : do not include datetime'
  print '--noepoch : do not include epochs'
  sys.exit(-1)

if '--modes' in args:
    print 'Saving backup of current archiving configuration'
    hdb = PyTangoArchiving.ArchivingAPI('hdb')
    tdb = PyTangoArchiving.ArchivingAPI('tdb')
    lines = []
    for a,v in hdb.items():
        if v.archiver:
            for m,p in v.modes.items():
                lines.append('\t'.join(map(str,[a,'hdb',v.archiver,m]+p)))
        else:
            lines.append('\t'.join(map(str,[a,'hdb']+['']*3)))
    for a,v in tdb.items():
        if v.archiver:
            for m,p in v.modes.items():
                lines.append('\t'.join(map(str,[a,'tdb',v.archiver,m]+p)))
        else:
            lines.append('\t'.join(map(str,[a,'tdb']+['']*3)))
    lines = sorted(lines)
    
elif '--config' in args:
    print 'Saving backup of current archiving configuration (human readable)'
    hdb = PyTangoArchiving.ArchivingAPI('hdb')
    tdb = PyTangoArchiving.ArchivingAPI('tdb')
    lines = []
    for api in (hdb,tdb):
      for a,v in api.items():
        if v.archiver:
          for m,p in v.modes.items():
            dev,attr = a.rsplit('/',1)
            m,p[0] = m.replace('MODE_P','periodic').replace('MODE_A','absolute').replace('MODE_R','relative'),int(p[0]/1e3)
            lines.append('\t'.join(map(str,[api.db.host,dev,attr,api.schema.upper(),m]+p)))
        elif api is hdb or a not in hdb:
          lines.append('\t'.join(map(str,[api.db.host,dev,attr,'STOP']+['']*3)))
    lines = sorted(lines)
    
else:
    # Getting the right Reader object
    if '--hdb' in args: rd = PyTangoArchiving.reader.Reader('hdb')
    elif '--tdb' in args: rd = PyTangoArchiving.reader.Reader('tdb')
    else: rd = PyTangoArchiving.reader.Reader() 
    if rd.schema.lower()=='tdb': print 'Using only TDB values'
        
    print 'The list of attributes is: %s'%attrs
    if len(attrs) == 1 and '.csv' in attrs[0]:
        try: attrs = PyTangoArchiving.ParseCSV(attrs[0]).keys()
        except: pass
    
    print 'Attributes: %s\nStart: %s\nStop: %s\n'%(attrs,start,stop)
    correlate = len(attrs)>1
    import codecs
    for a in args:
        if a.startswith('--resolution='):
            correlate = float(a.replace('--resolution=',''))
            print 'Correlation step set to %3.2f s'%correlate
        if a.startswith('--arrsep='):
            arrsep = a.split('=',1)[-1]
            arrsep = codecs.escape_decode(arrsep)[0]
        if a.startswith('--sep='):
            sep = a.split('=',1)[-1]
            sep = codecs.escape_decode(sep)[0]
        if a.startswith('--linesep='):
            linesep = a.split('=',1)[-1]
            linesep = codecs.escape_decode(linesep)[0]
        if a == '--nosep':
            sep = arrsep = ' '
            
    raws = rd.get_attributes_values(attrs,start,stop,text=False,correlate=False)
    values = fun.SortedDict()
    for a in attrs: values[a] = raws[a]
    print 'Obtained data from database:'
    print ' \n'.join(sorted('%s: %d values'%(a,len(v)) for a,v in values.items()))
    ll = max(len(v) for v in values.values())-1
    if correlate:
        print 'Filtering %d arrays (1/%dT)'%(len(values),correlate)
        import fandango
        for a,v in values.items():
            try:
                values[a] = fandango.arrays.filter_array(v,window=correlate)
            except Exception,e:
                print(e)
                print('Unable to correlate %s data, please try to export it '
                      'to a separate file' % a)
                values.pop(a);

        if not values:
            print('Unable to export data ...')
            sys.exit()
            
        if len(attrs)>1:
          try:
            Ts = (max(v[0][0] for v in values.values()),
                  min(v[-1][0] for v in values.values()))
            #print('interval: %s : %s' % (str(Ts), map(fandango.time2str,Ts)))
            for a,v in values.items():
                values[a]=[t for t in v if Ts[0]<=t[0]<=Ts[-1]]
            print sorted((a,len(v)) for a,v in values.items())
          except: traceback.print_exc()
    
    options = {'arrsep':arrsep,'sep':sep,'linesep':linesep}
    print 'Options: %s'%options
    data = PyTangoArchiving.Reader.export_to_text(
        values,order=attrs,**options).replace('None','NaN')
    
    #Remove repeated dates
    lines = data.split(linesep)
    ll = i = len(lines)-1
    while i:
        #if lines[i].split('\t')[1]==lines[i-1].split('\t')[1]:
        if lines[i] == lines[i-1]:
            lines.pop(i-1)
        i-=1
    #print 'data reduction: %s -> %s' % (ll,len(lines))        
    
    skip = 0 if '--nodate' in args else (1 if '--noepoch' in args else None)
    if skip is not None:
        for i,l in enumerate(lines):
            l = l.split(sep)
            try:
                l.pop(skip)
                lines[i] = sep.join(l)
            except:
                print(i,l,'?')
            
    if '--noheader' in args:
        lines = lines[1:]

print 'Writing %s'%filename
data = linesep.join(lines)
open(filename,'w').write(data)
