"""Extract from each NOAA CPC outlook page (raw/noaa/YYYY_Month.html): ranges for named storms,
hurricanes, major hurricanes, ACE (% of median), category probabilities, and whether a probability
for the ranges is stated. Prints a review table; writes data/noaa_extracted.csv."""
import re, glob, os, html, csv
def text(fn):
    t = open(fn, 'rb').read().decode('latin-1')
    t = re.sub(r'(?is)<(script|style).*?</\1>', ' ', t)
    t = html.unescape(re.sub(r'<[^>]+>', ' ', t))
    t = t.replace('\x96', '-').replace('–', '-').replace('—', '-').replace('\xa0', ' ')
    return re.sub(r'\s+', ' ', t)
R = r'(\d{1,2})\s*(?:-|to)\s*(\d{1,2})'
rows = []
for fn in sorted(glob.glob('../raw/noaa/*.html')):
    y, m = os.path.basename(fn)[:-5].split('_')
    t = text(fn)
    def first(pat):
        mm = re.search(pat, t, re.I); return (mm.group(1) + '-' + mm.group(2)) if mm else ''
    ns = first(R + r'\s*(?:named storms|named tropical storms|tropical storms)')
    h = first(R + r'\s*(?:hurricanes|(?:are expected to |could )?become hurricanes)')
    mh = first(R + r'\s*(?:major hurricanes|(?:are expected to |could )?become major)')
    ace = first(r'ACE[^.]{0,80}?(\d{2,3})\s*%?\s*(?:-|to)\s*(\d{2,3})\s*%')
    pa = re.search(r'(\d{1,3})\s*%\s*(?:chance|probability|likelihood)?\s*(?:of\s*(?:an?\s*)?)?above[- ]normal', t, re.I)
    pn = re.search(r'(\d{1,3})\s*%\s*(?:chance|probability|likelihood)?\s*(?:of\s*(?:an?\s*)?)?near[- ]normal', t, re.I)
    pb = re.search(r'(\d{1,3})\s*%\s*(?:chance|probability|likelihood)?\s*(?:of\s*(?:an?\s*)?)?below[- ]normal', t, re.I)
    p70 = re.search(r'(\d{2})\s*%\s*(?:probability|chance|likelihood)\s*(?:for|of)\s*(?:each|the following)', t, re.I)
    sev = '7 out of 10' in t
    rows.append(dict(year=y, month=m, ns=ns, h=h, mh=mh, ace_pct=ace,
                     p_above=pa.group(1) if pa else '', p_near=pn.group(1) if pn else '', p_below=pb.group(1) if pb else '',
                     range_prob=p70.group(1) if p70 else ('70' if sev else ''), nchars=len(t)))
with open('../data/noaa_extracted.csv', 'w', newline='') as fh:
    w = csv.DictWriter(fh, rows[0].keys()); w.writeheader(); w.writerows(rows)
for r in rows: print(' '.join(f'{v}' for v in r.values()))
