#!/usr/bin/env python3
"""Validate the complete set of generated shipping datasets before publication."""
import json
import math
from collections import Counter
from pathlib import Path

ROOT=Path(__file__).resolve().parent
minimums={'shipping.geojson':100,'shipping_extra.geojson':10,'shipping_fedex.geojson':200,'shipping_ups_boxes.geojson':100}
for name,minimum in minimums.items():
    data=json.loads((ROOT/name).read_text())
    assert data.get('type')=='FeatureCollection',name
    features=data['features']
    assert len(features)>=minimum,(name,len(features))
    for f in features:
        g=f['geometry'];p=f['properties'];c=g['coordinates']
        assert g['type']=='Point' and len(c)==2,(name,g)
        assert all(isinstance(v,(int,float)) and math.isfinite(v) for v in c),(name,c)
        assert -75.57<=c[0]<=-73.88 and 38.88<=c[1]<=41.36,(name,c)
        assert p.get('carrier') and p.get('source'),(name,p)
    counts=Counter(f['properties']['carrier'] for f in features)
    if 'location_quality' in data:
        quality_counts=Counter()
        for f in features:
            p=f['properties']
            if 'All The Places' not in p['source'] and 'MailingLocations' not in p['source']:continue
            q=p.get('location_quality') or {}
            assert q.get('version')==1 and q.get('status') in ('checked','corrected','unresolved'),(name,p)
            assert p.get('position_quality'),(name,p)
            original=q.get('original_coordinates')
            assert isinstance(original,list) and len(original)==2 and all(isinstance(v,(int,float)) and math.isfinite(v) for v in original),(name,q)
            if q['status']=='corrected':
                assert f['geometry']['coordinates']==q['reference_coordinates'],(name,q)
                assert q.get('reference_id') and q.get('reference_source') and p.get('coordinate_source'),(name,q)
            quality_counts[q['status']]+=1
        assert dict(quality_counts)==data['location_quality']['counts'],(name,quality_counts)
        print(f'{name} coordinate quality: {dict(quality_counts)}')
    if name=='shipping.geojson':
        boxes=[f for f in features if f['properties']['carrier']=='USPS' and f['properties'].get('location_type')=='drop_box']
        assert len(boxes)>=1000,('Missing USPS collection boxes',len(boxes))
        assert len({f['properties']['ref'] for f in boxes})==len(boxes),'Duplicate USPS box references'
        assert all(f['properties']['source']=='USPS locator via All The Places' for f in boxes)
        assert all('collection_times' in f['properties'] for f in boxes)
    if name=='shipping_extra.geojson':assert counts['CVS UPS']>0 and counts['All The Places']>0
    if name=='shipping_fedex.geojson':
        assert all(f['properties']['carrier']=='FedEx' for f in features)
        assert all(f['properties']['location_type'] in ('staffed','drop_box') for f in features)
    if name=='shipping_ups_boxes.geojson':
        assert len({f['properties']['ref'] for f in features})==len(features)
        assert all(f['properties']['source_url'].startswith('https://www.mailinglocations.com/') for f in features)
    print(f'{name}: {len(features)} valid points; {dict(counts)}')
print('All shipping data checks passed')
