#!/usr/bin/python
# -*- coding: utf-8 -*-
__copyright__ = """

    Copyright 2019 Samapriya Roy

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

"""
__license__ = "Apache 2.0"

import requests
import json
import os
import glob
import sys
from planet.api.auth import find_api_key

# Get API key and authenticate session
try:
    PL_API_KEY = find_api_key()
except Exception as e:
    print('Failed to get Planet Key')
    sys.exit()
SESSION = requests.Session()
SESSION.auth = (PL_API_KEY, '')

l=[]


def handle_page(page, asset):
    try:
        for items in page['features']:
            for itm in items['_permissions']:
                if itm.split(':')[0]=="assets."+asset:
                    it=items.get('id')
                    #print(it)
                    l.append(it)
    except Exception as e:
        print(e)


def idl(infile, start, end, item, asset, cmin, cmax):
    if cmin is None:
        cmin = 0
    if cmax is None:
        cmax = 1
    headers = {'Content-Type': 'application/json'}

# Parse Geometry
    try:
        if infile.endswith('.geojson'):
            with open(infile) as aoi:
                aoi_resp = json.load(aoi)
                aoi_geom = aoi_resp['features'][0]['geometry']['coordinates']
        elif infile.endswith('.json'):
            with open(infile) as aoi:
                aoi_resp = json.load(aoi)
                aoi_geom = aoi_resp['config'][0]['config']['coordinates']
    except Exception as e:
        print('Could not parse geometry')
        print(e)
# Null payload structure
    data = {'filter': {'type': 'AndFilter',
            'config': [{'type': 'GeometryFilter', 'field_name': 'geometry',
            'config': {'type': 'Polygon', 'coordinates': []}},
            {'type': 'OrFilter', 'config': [{'type': 'AndFilter',
            'config': [{'type': 'StringInFilter', 'field_name': 'item_type'
            , 'config': []}, {'type': 'RangeFilter',
            'field_name': 'cloud_cover', 'config': {'gte': [],
            'lte': []}}, {'type': 'RangeFilter',
            'field_name': 'sun_elevation', 'config': {'gte': 0,
            'lte': 90}}]}]}, {'type': 'OrFilter',
            'config': [{'type': 'DateRangeFilter', 'field_name': 'acquired'
            , 'config': {'gte': [],
            'lte': []}}]}]},
            'item_types': []}
# Configure search payload
    data['filter']['config'][0]['config']['coordinates'] = aoi_geom
    data['filter']['config'][2]['config'][0]['config']['gte'] = str(start)+'T04:00:00.000Z'
    data['filter']['config'][2]['config'][0]['config']['lte'] = str(end)+'T03:59:59.999Z'
    data['filter']['config'][1]['config'][0]['config'][1]['config']['gte'] = float(cmin)
    data['filter']['config'][1]['config'][0]['config'][1]['config']['lte'] = float(cmax)
    data['filter']['config'][1]['config'][0]['config'][0]['config'] = [item]
    data['item_types'] = [item]
    data = str(data).replace("'", '"')

# Send post request
    result = SESSION.post('https://api.planet.com/data/v1/quick-search',
                           headers = headers, data = data)
    if result.status_code==408:
        sys.exit('Unexpected 408 Error might be intermittent try again in sometime')
    page = result.json()
    final_list = handle_page(page,asset)
    while page['_links'].get('_next') is not None:
        page_url = page['_links'].get('_next')
        page = SESSION.get(page_url).json()
        ids = handle_page(page,asset)
    print('Searched total IDs: '+str(len(l)))
    return set(l)


def checker(folder, typ, infile, item, asset, start, end, cmin, cmax,outfile):
    print('Now Searching....')
    allasset = idl(infile = infile, item = item, asset = asset, start = start, end = end, cmin = cmin, cmax = cmax)
    sprefix = {'PSScene4Band': '_3B', 'REOrthoTile': '_R', 'PSScene3Band': '_3B', 'PSOrthoTile': '_BGRN'}
    sval = sprefix.get(item)
    if typ == 'image':
        filenames = glob.glob1(folder,"*.tif")
        l = []
        for items in filenames:
            l.append(items.split(sval)[0])
        print('Number of items not found locally: '+str(len(set(allasset)-set(l))))
        print('IDlist written to '+str(outfile)+' with '+str(len(set(allasset)-set(l))))
        with open(outfile, "w") as f:
            for s in list(set(allasset)-set(l)):
                f.write(str(s) +"\n")
    if typ=='metadata':
        filenames=glob.glob1(folder,"*.xml")
        l=[]
        for items in filenames:
            l.append(items.split(sval)[0])
        print('Number of items not found locally: '+str(len(set(allasset).difference(set(l)))))
        print('IDlist written to '+str(outfile)+' with '+str(len(set(allasset)-set(l)))+' ids')
        with open(outfile, "w") as f:
            for s in list(set(allasset)-set(l)):
                f.write(str(s) +"\n")

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='Checks the difference between local files and all available Planet assets')
    parser.add_argument('--folder', help='local folder where image or metadata files are stored', required=True)
    parser.add_argument('--typ', help='File type image or metadata', required=True)
    parser.add_argument('--input', help='Input boundary to search (geojson, json)', required=True)
    parser.add_argument('--item', help='Planet Item Type', required=True)
    parser.add_argument('--asset', help='Planet asset Type', required=True)
    parser.add_argument('--start', help='Start Date YYYY-MM-DD', required=True)
    parser.add_argument('--end', help='End Date YYYY-MM-DD', required=True)
    parser.add_argument('--cmin', help='Minimum cloud cover', required=False,default=None)
    parser.add_argument('--cmax', help='Maximum cloud cover', required=False,default=None)
    parser.add_argument('--outfile', help='Full path to text file with difference ID list', required=True)

    args = parser.parse_args()

    checker(folder=args.folder,typ=args.typ,infile=args.input,
        item=args.item,asset=args.asset,start=args.start,end=args.end,
        cmin=args.cmin,cmax=args.cmax,outfile=args.outfile)
# checker(folder=r'C:\Users\samapriya\Box Sync\IUB\Pycodes\Applications and Tools\Planet Tools\DiffCheck\ps4bxml',typ='metadata',
#     infile=r'C:\Users\samapriya\Box Sync\IUB\Pycodes\Applications and Tools\Planet Tools\DiffCheck\geojson\Grid_3.geojson',
#     item='PSScene4Band',asset='analytic',start='2018-01-01',end='2018-08-01',cmin=None,cmax=0.3,outfile='readme.txt')