import requests
import xml.etree.ElementTree as ET
import json

def propertiesGetter():
    """
    Requests XML file and stores a local copy.
    """
    data = requests.get('https://s3.amazonaws.com/abodo-misc/sample_abodo_feed.xml')

    with open('raw_feed.xml', 'wb') as file: file.write(data.content)

def propertiesParser(xml):
    """
    Takes in an XML file sourced from Rentable/ABODO, converts it to readable form, and iterates through its consituent elements. From this, generates a list of properties in the Madison area along with relevant information.

    Args:
        xml (XML file): Raw Rentable/ABODO property feed.

    Returns:
        properties (list): Processed list of properties and their individual units available for rent in the Madison area.
    """
    # XML feed data is parsed into a readable tree format
    tree = ET.parse(xml)
    root = tree.getroot()
    properties = []

    # iteration through each Property element in the tree to create property objects with relevant information
    for Property in root.findall('./Property'):

        # extraction of relevant information from child elements needed to complete property objects located in the Madison area
        if Property.findtext('./PropertyID/Address/City') == 'Madison':
            madison_property = {}
            madison_property['property_id'] = int(Property.find('./PropertyID/Identification').attrib['IDValue'])
            madison_property['name'] = Property.findtext('./PropertyID/MarketingName')
            madison_property['email'] = Property.findtext('./PropertyID/Email')
            madison_property['coordinates'] = (float(Property.findtext('./ILS_Identification/Latitude')), float(Property.findtext('./ILS_Identification/Longitude')))
            madison_property['weather_report'] = None
            madison_property['units'] = []

            # nested iteration through each Unit element in a given Property to create unit objects with relevant information
            for Unit in Property.findall('./ILS_Unit/Units/Unit'):
                madison_property_unit = {}
                madison_property_unit['unit_id'] = int(Unit.find('./Identification/[@IDType="UnitID"]').attrib['IDValue'])
                madison_property_unit['bedrooms'] = int(float(Unit.findtext('./UnitBedrooms')))
                madison_property['units'].append(madison_property_unit)

            # completed property object added to properties list for output
            properties.append(madison_property)
            
    return properties

def weatherGetter(properties):
    """
    Uses values stored in coordinates key for each property request locality-specific weather forecast information from a public API.

    Args:
        properties (list): Processed list of properties and their individual units available for rent in the Madison area.

    Returns:
        properties (list): Same as original argument, bu including additional data under each property's weather_report key.
    """
    # iteration through each property object in the list
    for property in properties:
        # first API call to request and parse top-level weather_data object
        weather_data = requests.get(f'https://api.weather.gov/points/{property["coordinates"][0]},{property["coordinates"][1]}')
        weather_data = json.loads(weather_data.content)
        # second API call using forecast URL within weather_data to request and parse actual foreacase information
        forecast = requests.get(weather_data['properties']['forecast'])
        forecast = json.loads(forecast.content)
        # forecast information added to each property's weather_report key
        property['weather_report'] = forecast['properties']['periods'][0]['detailedForecast']

    return properties

def jsonConverter(data):
    """
    Accepts list of parsed properties and converts it into JSON format for local storage.

    Args:
        data (list): List of parsed properties generated by propertiesParser function.
    """
    with open('processed_feed_madison_only.json', 'w') as file: json.dump(data, file, indent=2)

if __name__ == '__main__':
    propertiesGetter()
    properties = propertiesParser('raw_feed.xml')
    properties = weatherGetter(properties)
    jsonConverter(properties)

    print('properties = ' + json.dumps(properties, indent=2))