# Path: cmt/util/miscUtilities.py
# def safe_get_info(ee_object, max_num_attempts=5):
#     '''Keep trying to call getInfo() on an Earth Engine object until it succeeds.'''
#     
#     # Do not try again if we get one of these exceptions
#     fail_messages = ['Too many pixels']
#     
#     num_attempts = 0
#     while True:
#         try:
#             return ee_object.getInfo()
#         except Exception as e:
#             # Rethrow the exception if it is not timeout related
#             for message in fail_messages:
#                 if message in str(e):
#                     raise e
#                     
#             print('Earth Engine Error: %s. Waiting 10s and then retrying.' % (e))
#             time.sleep(10)
#             num_attempts += 1
#         if max_num_attempts and (num_attempts >= max_num_attempts):
#             raise Exception('safe_get_info failed to succeed after ' +str(num_attempts)+ ' attempts!')


import ee
from cmt.util.miscUtilities import safe_get_info
    score = score.min(expression_and_rescale(img, 'img.red + img.green + img.blue', [0.2, 0.8]))

    # Clouds are reasonably bright in all infrared bands.
    score = score.min(expression_and_rescale(img, 'img.nir + img.swir1 + img.swir2', [0.3, 0.8]))

    # Clouds are reasonably cool in temperature.
    score = score.min(expression_and_rescale(img, 'img.temp', [300, 290]))

    # However, clouds are not snow.
    ndsi  = img.normalizedDifference(['green', 'swir1'])
    score = score.min(expression_and_rescale(ndsi, 'img', [0.8, 0.6]))

    CLOUD_THRESHOLD = 0.35
    return score.gt(CLOUD_THRESHOLD)

def getCloudPercentage(image, region):
    '''Estimates the cloud cover percentage in a Landsat image'''
    
    # The function will attempt the calculation in these ranges
    # - Native Landsat resolution is 30
    MIN_RESOLUTION = 60
    MAX_RESOLUTION = 1000
    
    resolution = MIN_RESOLUTION
    while True:
        try:
            oneMask     = ee.Image(1.0)
            cloudScore  = detect_clouds(image)
            areaCount   = oneMask.reduceRegion(  ee.Reducer.sum(),  region, resolution)
            cloudCount  = cloudScore.reduceRegion(ee.Reducer.sum(), region, resolution)

# Path: cmt/util/miscUtilities.py
# def safe_get_info(ee_object, max_num_attempts=5):
#     '''Keep trying to call getInfo() on an Earth Engine object until it succeeds.'''
#     
#     # Do not try again if we get one of these exceptions
#     fail_messages = ['Too many pixels']
#     
#     num_attempts = 0
#     while True:
#         try:
#             return ee_object.getInfo()
#         except Exception as e:
#             # Rethrow the exception if it is not timeout related
#             for message in fail_messages:
#                 if message in str(e):
#                     raise e
#                     
#             print('Earth Engine Error: %s. Waiting 10s and then retrying.' % (e))
#             time.sleep(10)
#             num_attempts += 1
#         if max_num_attempts and (num_attempts >= max_num_attempts):
#             raise Exception('safe_get_info failed to succeed after ' +str(num_attempts)+ ' attempts!')


# Path: cmt/util/landsat_functions.py
import ee
from cmt.util.miscUtilities import safe_get_info

    score = score.min(expression_and_rescale(img, 'img.red + img.green + img.blue', [0.2, 0.8]))

    # Clouds are reasonably bright in all infrared bands.
    score = score.min(expression_and_rescale(img, 'img.nir + img.swir1 + img.swir2', [0.3, 0.8]))

    # Clouds are reasonably cool in temperature.
    score = score.min(expression_and_rescale(img, 'img.temp', [300, 290]))

    # However, clouds are not snow.
    ndsi  = img.normalizedDifference(['green', 'swir1'])
    score = score.min(expression_and_rescale(ndsi, 'img', [0.8, 0.6]))

    CLOUD_THRESHOLD = 0.35
    return score.gt(CLOUD_THRESHOLD)

def getCloudPercentage(image, region):
    '''Estimates the cloud cover percentage in a Landsat image'''
    
    # The function will attempt the calculation in these ranges
    # - Native Landsat resolution is 30
    MIN_RESOLUTION = 60
    MAX_RESOLUTION = 1000
    
    resolution = MIN_RESOLUTION
    while True:
        try:
            oneMask     = ee.Image(1.0)
            cloudScore  = detect_clouds(image)
            areaCount   = oneMask.reduceRegion(  ee.Reducer.sum(),  region, resolution)
            cloudCount  = cloudScore.reduceRegion(ee.Reducer.sum(), region, resolution)

            percentage  = safe_get_info(cloudCount)['constant'] / safe_get_info(areaCount)['constant']