#! /usr/bin/env python3

import argparse
import cairo

from xmet.config import Config
from xmet.db     import Database

from xmet.spc import SPCOutlookParser, \
                     SPCOutlook, \
                     SPCOutlookMap, \
                     SPCOutlookType

def render_categorical(db: Database,
                       conus: SPCOutlookMap,
                       outlook: SPCOutlook,
                       args):
    assets = {
        'conus': config['map']['conus_dark' if args.dark else 'conus'],
        'logo':  config['map']['logo_dark'  if args.dark else 'logo']
    }

    with cairo.SVGSurface(args.categorical, conus.width, conus.height) as surface:
        cr = cairo.Context(surface)

        conus.draw_base_map_from_file(cr, assets['conus'])
        conus.draw_categories(cr, outlook)

        if args.cities:
            conus.draw_cities(cr, db)

        conus.draw_logo(cr, assets['logo'])
        conus.draw_legend(cr, SPCOutlookType.CATEGORICAL)

        if args.dark:
            cr.set_source_rgb(1, 1, 1)

        conus.draw_annotation(cr, outlook, SPCOutlookType.CATEGORICAL)

def render_probabilistic(db: Database,
                         conus: SPCOutlookMap,
                         outlook: SPCOutlook,
                         hazard: str,
                         path: str,
                         args):
    assets = {
        'conus': config['map']['conus_dark' if args.dark else 'conus'],
        'logo':  config['map']['logo_dark'  if args.dark else 'logo']
    }

    with cairo.SVGSurface(path, conus.width, conus.height) as surface:
        cr = cairo.Context(surface)

        conus.draw_base_map_from_file(cr, assets['conus'])
        conus.draw_probabilities(cr, outlook, hazard.upper())

        if args.cities:
            conus.draw_cities(cr, db)

        conus.draw_logo(cr, assets['logo'])
        conus.draw_legend(cr, SPCOutlookType.PROBABILISTIC)

        if args.dark:
            cr.set_source_rgb(1, 1, 1)

        hazard = ' '.join(map(lambda p: p.lower().capitalize(), hazard.split(' ')))

        conus.draw_annotation(cr, outlook, SPCOutlookType.PROBABILISTIC, hazard)

argparser = argparse.ArgumentParser(description='Render graphical SPC outlooks from text file')
argparser.add_argument('--dark',   action='store_true', help='Output dark mode graphics')
argparser.add_argument('--cities', action='store_true', help='Render major cities')
argparser.add_argument('--file',        type=str, help='Load outlook from file, not database')
argparser.add_argument('--valid',       type=str, help='Timestamp on or after most recent outlook')
argparser.add_argument('--day',         type=int, help='Number of days from issuance outlook applies to')
argparser.add_argument('--categorical', type=str, help='Output categorical risk graphic file')
argparser.add_argument('--any-severe',  type=str, help='Output probabilistic severe risk graphic file')
argparser.add_argument('--tornado',     type=str, help='Output probabilistic hail risk graphic file')
argparser.add_argument('--hail',        type=str, help='Output probabilistic hail risk graphic file')
argparser.add_argument('--wind',        type=str, help='Output probabilistic wind risk graphic file')

args = argparser.parse_args()

config = Config.load()
db     = Database.from_config(config)

conus  = SPCOutlookMap()

if args.file is None:
    outlook = SPCOutlook.for_timestamp(db, args.valid, args.day)
else:
    with open(args.file, 'r') as fh:
        parser = SPCOutlookParser()

        outlook = parser.parse(fh.read())

if args.categorical is not None:
    render_categorical(db, conus, outlook, args)

if args.any_severe is not None:
    render_probabilistic(db, conus, outlook, 'any severe', args.any_severe, args)

if args.tornado is not None:
    render_probabilistic(db, conus, outlook, 'tornado', args.tornado, args)

if args.hail is not None:
    render_probabilistic(db, conus, outlook, 'hail', args.hail, args)

if args.wind is not None:
    render_probabilistic(db, conus, outlook, 'wind', args.wind, args)