# -*- coding: utf-8 -*-
# 2009-11-30 Moritz

from obspy.core import UTCDateTime
from obspy.arclink import Client
import pickle, os, threading, time, sys

def savePaz(client, paz_file, network, station, location, channel, start, end):
    """
    Function automating saving of paz
    """
    paz = client.getPAZ(network, station, location, channel, start, end)
    pickle.dump(paz, open(paz_file,'wb'))

def monitor(fct, args, timeout=25):
    """
    Monitor fct. Return True if function finished, returns False if
    function did not finish after timeout seconds
    start it again.

    @param fct: Function to monitor
    @param args: Arguments of function as tuple
    @param timeout: Timeout in seconds
    @return: True of False depending if function did finish in timeout
             seconds
    """
    # count number of current active threads
    nthreads = threading.activeCount()
    # start new thread
    thread = threading.Thread(target=fct, args=args)
    thread.daemon = True
    thread.start()
    start = time.time()
    # Loop until thread is finished or timeout is reached
    while True:
        if threading.activeCount() == nthreads:
            return True
        # Avoid infinite loop and leave after timeout seconds 
        elif time.time() - start >= timeout:
            return False
        else:
            time.sleep(0.5)
            # Immediate printing
            sys.stdout.write(str(threading.activeCount())+" ")
            sys.stdout.flush()
            continue

def save_all(network, stations, channel, start, end):
    """
    Save data as MiniSEED and PAZ as Python dump. Watchdog controlled. If
    file is not downloaded start download again.

    @param network: The network id
    @param stations: List of stations ids
    @param channel: The channel id
    @param start: start datetime as UTCDateTime
    @param end: end datetime as UTCDateTime
    """
    for station in stations:
        mseed_file = "%s.%s.%s.%s.D.%s" % (network ,station,'',channel,t.strftime("%Y.%j"))
        paz_file = "%s.%s.%s.%s.D.paz" % (network ,station,'',channel)
        while True:
            try:
                client = Client("webdc.eu", timeout=None, debug=False)
                if not os.path.exists(mseed_file):
                    errcode = monitor(client.saveWaveform, (mseed_file, network, \
                                      station, '', channel, start, end))
                    if errcode == False:
                        continue
                elif not os.path.exists(paz_file):
                    errcode = monitor(savePaz, (client, paz_file, network, \
                                      station, '', channel, start, end))
                    if errcode == False:
                        continue
                else:
                    print "Data and paz for station %s are now available" % (station)
                    break
            except Exception, e:
                print e, "Cannot retrieve data and/or paz for station", station
                break





###############################################################################################
#########                                                                    ##################
#########                      Start of Main Program                         ##################
#########                                                                    ##################
###############################################################################################



#
# Local earthquake Bavaria and corresponding stations
#
t = UTCDateTime("2008-04-17 16:00:20") 
network = 'BW'
stations = ['RJOB','RNON','RMOA']
channel = 'EHZ'
save_all(network, stations, channel, t, t+60) #1 minute

#
# Seismic noise, nothing in it
#
t = UTCDateTime("2008-04-16 16:00:20") 
network = 'BW'
stations = ['RJOB','RNON','RMOA']
channel = 'EHZ'
save_all(network, stations, channel, t, t+60) #1 minute

#
# Sumatra earthquake and corresponding stations
#
t = UTCDateTime(2004,12,26,01,00,00)
network = 'GR'
stations = ['FUR','BFO','BRG','BSEG','BUG']
channel = 'LHZ'
save_all(network, stations, channel, t, t + (5*3600)) #5 hours
save_all(network, ['FUR'], 'LHN', t, t + (5*3600)) #5 hours
save_all(network, ['FUR'], 'LHE', t, t + (5*3600)) #5 hours

#
# China earthquake, get a whole day
#
t = UTCDateTime("2008,133,5:17:48.640") #year day 133
save_all('GR',['FUR'], 'LHZ', t, t+(3600*23.9))
save_all('GR',['FUR'], 'LHE', t, t+(3600*23.9))
# Some noise before
t = UTCDateTime("2008,131,5:17:48.640") #year day 133
save_all('GR',['FUR'], 'LHZ', t, t+(3600*23.9))

#
# Hokkaido earthquake September 25, 2003
#
t = UTCDateTime("2003-09-25 19:50")
save_all('GR',['FUR'], 'LHN', t, t+(3600*5))
save_all('GR',['FUR'], 'LHE', t, t+(3600*5))
save_all('GR',['FUR'], 'LHZ', t, t+(3600*5))


sys.exit(0)
