"""Get latest observations from Port Authority of NSW and update local copy.

Station IDs are below:

02: Offshore (Directional) Wave
03: Bombora (Directional) Wave
04: Captain Cook Channel (SG) Wave
05: Kurnell (SG) Wave
06: Molineaux Point Wind
07: Sydney Airport (Main Runway BOM) Wind
08: Brotherson Emergency Response Jetty Tide
09: Caltex (Directional) Current
12: Western Wedding Cake Wind
13: Fort Denison (Sth end BOM) Wind
14: Overseas Passenger Terminal Wind
15: Glebe Island Wind
16: Fort Denison-Primary (Nth end) Tide
17: Fort Denison-Secondary (Vegapuls64) Tide
18: Circular Quay ADCP Current
19: Balls Head Current
22: Twofold Bay - Munganno Point Wave
23: Twofold Bay - Multipurpose Wharf Wind
24: Breakwater Wharf Wind
27: Middle Wall (Vegapulse WL61) Tide
28: Goodwood (Vegapulse WL61) Tide

D. Howe
2019-09-16
"""

import os
import re
import datetime
import requests
import pandas as pd
from lxml import html

output_dir = 'csv'
stn_ids = [
    2,  # Offshore (Directional) Wave
    3,  # Bombora (Directional) Wave
    4,  # Captain Cook Channel (SG) Wave
    5,  # Kurnell (SG) Wave
    6,  # Molineaux Point Wind
    7,  # Sydney Airport (Main Runway BOM) Wind
    8,  # Brotherson Emergency Response Jetty Tide
    9,  # Caltex (Directional) Current
    12,  # Western Wedding Cake Wind
    13,  # Fort Denison (Sth end BOM) Wind
    14,  # Overseas Passenger Terminal Wind
    15,  # Glebe Island Wind
    16,  # Fort Denison-Primary (Nth end) Tide
    17,  # Fort Denison-Secondary (Vegapuls64) Tide
    18,  # Circular Quay ADCP Current
    19,  # Balls Head Current
    22,  # Twofold Bay - Munganno Point Wave
    23,  # Twofold Bay - Multipurpose Wharf Wind
    24,  # Breakwater Wharf Wind
    27,  # Middle Wall (Vegapulse WL61) Tide
    28,  # Goodwood (Vegapulse WL61) Tide
]


def update_master(output_dir, csv_name, df):
    """Update master csv time series.

    Args:
        output_dir (str): path to time series directory
        csv_name (str):   name of time series file
        df (dataframe):   dataframe with datetime index

    Returns:
        None
    """
    try:
        # Load local master table if it exists
        master = pd.read_csv(os.path.join(output_dir, csv_name),
                             index_col=0,
                             parse_dates=True)

        # Only include timestamps that do not already exist
        df = df[~df.index.isin(master.index)]

        # Update master
        master = master.append(df)

    except FileNotFoundError:
        # Create new master table if none exists
        master = df

    # Export master table
    master.to_csv(os.path.join(output_dir, csv_name))


def main(stn_id):
    """Extract current parameters for selected station.

    Args:
        stn_id (int): station ID

    Returns:
        None
    """

    # Get elements from selected station
    t_raw = tree.get_element_by_id(f'MainContent_ctl{stn_id:02}_lblRecordDate')
    meas = tree.get_element_by_id(f'MainContent_ctl{stn_id:02}_lblSummary')
    description = tree.get_element_by_id(
        f'MainContent_ctl{stn_id:02}_lblTitle')

    # Parse column names
    text = re.split(':\s|(m|s|knots|deg)\s', meas.text + ' ')
    parts = [t for t in text if t]
    parameters = [p.strip() for p in parts[::3]]
    values = [float(p) for p in parts[1::3]]
    units = parts[2::3]
    columns = [f'{p} ({u})' for p, u in zip(parameters, units)]

    # Parse time
    time = re.search('at ([0-9]{4})', t_raw.text).group(1)
    date = t_raw.text.split(',')[1].strip()
    t = datetime.datetime.strptime(date + time, '%d %b %Y%H%M')

    # Create dataframe
    df = pd.DataFrame({c: v for c, v in zip(columns, values)}, index=[t])
    df.index.name = 'datetime'

    # Update master dataframe
    csv_name = description.text + '.csv'
    update_master(output_dir, csv_name, df)


# Get main page
url = 'http://wavewindtide.portauthoritynsw.com.au/'
page = requests.get(url)
tree = html.fromstring(page.content)

for stn_id in stn_ids:
    try:
        main(stn_id)
    except (TypeError, KeyError):
        pass
