#!/usr/bin/python

import os
import sys
from optparse import OptionParser
import psycopg2
import cStringIO



def get_command_line_options():
    usage_summary = '%prog [options]'
    program_description = 'Obtain a sanitized list of locations of all stations that should be loaded into the parch database'
    parser = OptionParser(usage = usage_summary, 
                          version = '%prog 0.8', 
                          description = program_description,
                          conflict_handler = 'resolve')

    parser.add_option('--no-automatic-stations', action='store_false', dest='automatic_stations', help='Skip selecting stations, based on any algorithm')
    parser.add_option('--load-file', metavar='FILE', default='/etc/parch-util/foreign_stations.txt', help='Get extra stations list from the given file instead of the default file')
    parser.add_option('--url', action='store_true', dest='print_urls', help='instead of coordinates, print URL to acquire data from api.met.no')

    db = parser.add_option_group('Database connection')
    db.add_option('-d', '--database', default='wdb', help='database name (ex. wdb)')
    db.add_option('-h', '--host', help='database host (ex. somehost.met.no)')
    db.add_option('-u', '--user', default=os.getenv('USER'), help='database user name')
    db.add_option('-p', '--port', type='int', help='database port number to connect to')
    
    parsed = parser.parse_args()
    return parsed

def get_connect_string(options):
    connect = cStringIO.StringIO()
    connect.write('dbname=' + options.database)
    if options.host is not None:
        connect.write(' host=' + options.host)
    if options.port is not None:
        connect.write(' port=' + str(options.port))
    connect.write(' user=' + options.user)
    return connect.getvalue()


class StationGenerator(object):
    def __init__(self, options):
        self.connection = psycopg2.connect(get_connect_string(options))

    def get_norwegian_stations(self):
        cursor = self.connection.cursor()
        cursor.execute("SELECT wci.begin('wdb', 88,456,88)")
        cursor.execute("SELECT x(placegeometry), y(placegeometry) FROM wci.getplacepoint(NULL) WHERE placename::int >= 1000 AND placename::int <= 2000")
        result = cursor.fetchone()
        while result is not None:
            yield result
            result = cursor.fetchone()
    
    
    def get_extra_stations(self, wmo_number_list):
        
        cursor = self.connection.cursor()
        for n in wmo_number_list:
            if not n:
                continue
            cursor.execute("SELECT wci.begin('wdb', 88,456,88)")
            cursor.execute("SELECT x(placegeometry), y(placegeometry) FROM wci.getplacepoint(%s)", (n,))
            elements = cursor.fetchall()
            length = len(elements)
            if length == 0:
                sys.stderr.write('No location for wmo number ' + str(n) + '\n')
            elif length > 1:
                sys.stderr.write('Many locations for wmo number ' + str(n) + " ( ")
                for n in elements:
                    sys.stderr.write('%f,%f ' % (n[0], n[1]))
                sys.stderr.write(")\n")
            else:
                yield elements[0]


def read_extra_data_file(file_name):
    f = file(file_name)
    for line in f:
        yield line.split(',')[0].strip()

def stations_to_list(options):
    generator = StationGenerator(options)
    if options.automatic_stations is None or options.automatic_stations == True:
        for station in generator.get_norwegian_stations():
            yield station
            
    if options.load_file:
        wmo_number_list = read_extra_data_file(options.load_file)
        for station in generator.get_extra_stations(wmo_number_list):
            yield station

def get_url(latlon):
    return 'http://api.met.no/weatherapi/locationforecast/1.8/?lat=%f;lon=%f' % (latlon[1], latlon[0]) 

if __name__ == '__main__':

    try:
        options, extra = get_command_line_options()
    
        if len(extra) > 0:
            sys.stderr.write('Unrecognized options: ' + str(extra))
            sys.exit(1)

        locations = {}
        for station in stations_to_list(options):
            locations[station] = None

        for location in locations: 
            if options.print_urls:
                print get_url(location)
            else:
                print location[1], location[0]

    except Exception, e:
        sys.stderr.write('FATAL: %s\n' % (e,))
        sys.exit(1)
