
"""
Gridded data is already aggregated by month

therefore we don't have daily gridded data, but this is 
importing to the same basic table type as if it were daily.

So:
Don't make a daily table
Record what monthly aggregations are available
We only use monthly aggregations on the map and chart so

Some statistics won't be available depending on the aggregation of the gridded data.

Rainfall:
SUM -> AVERAGE -> COUNT

We want SUM

Temp:
We want MAX, MIN, 

Or:
  record what time_period means in the table.
  aggregate month tables into year tables
  leave daily tables empty so that we just don't get any values to add
  but the table is ready there in case the values ever turn up.
  
NetCDF data includes units information so need to use this to convert the data.

"""

ClimateDataPortal = local_import("ClimateDataPortal")
InsertChunksWithoutCheckingForExistingReadings = local_import(
    "ClimateDataPortal.InsertChunksWithoutCheckingForExistingReadings"
).InsertChunksWithoutCheckingForExistingReadings

def get_or_create(dict, key, creator):
    try:
        value = dict[key]
    except KeyError:
        value = dict[key] = creator()
    return value

def get_or_create_record(table, query):
    query_terms = []
    for key, value in query.iteritems():
        query_terms.append(getattr(table, key) == value)
    reduced_query = reduce(
        (lambda left, right: left & right),
        query_terms
    )
    records = db(reduced_query).select()
    count = len(records)
    assert count <= 1, "Multiple records for %s" % query
    if count == 0:
        record = table.insert(**query)
        db.commit()
    else:
        record = records.first()
    return record.id

def nearly(expected_float, actual_float):
    difference_ratio = actual_float / expected_float
    return 0.999 < abs(difference_ratio) < 1.001

class InsertRowsIfNoConflict(object):
    def __init__(self, database_table_name, db):
        raise NotImplemented
        self.database_table = database_table
    
    def add_reading(
        self,
        time_period,
        place_id,
        value
    ):
        database_table = self.database_table
        records = db(
            (database_table.time_period == time_period) &
            (database_table.place_id == place_id)
        ).select(database_table.value, database_table.id)
        count = len(records)
        assert count <= 1
        if count == 0:
            database_table.insert(
                time_period = time_period,
                place_id = place_id,
                value = value
            )
        else:
            existing = records.first()
            assert nearly(existing.value, value), (existing.value, value, place_id)
    
    def done(self):
        pass
    
import datetime

def import_climate_readings(
    netcdf_file,
    field_name,
    add_reading,
    converter,
    start_time = datetime.date(1971,1,1),
    is_undefined = lambda x: -99.900003 < x < -99.9
):
    """
    Assumptions:
        * there are no places
        * the data is in order of places
    """
    variables = netcdf_file.variables
    if field_name is "?":
        print ("field_name could be one of %s" % variables.keys())
    else:
        # create grid of places
        place_ids = {}
        
        def to_list(variable):
            result = []
            for i in range(len(variable)):
                result.append(variable[i])