# -*- coding: utf-8 -*-
# Copyright (C) Duncan Macleod (2019)
#
# This file is part of GWpy.
#
# GWpy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GWpy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GWpy.  If not, see <http://www.gnu.org/licenses/>.

"""Fetch and parse an event catalog from GWOSC.
"""


from astropy import constants
from astropy import units

from gwosc.api import DEFAULT_URL as DEFAULT_GWOSC_URL
from gwosc.catalog import download as download_catalog

from .. import EventTable
from .utils import (
    read_with_columns,
    read_with_selection,
)

# handle custom GWOSC units
UNITS = {
    "M_sun X c^2": units.M_sun * constants.c ** 2,
}

__author__ = 'Duncan Macleod <duncan.macleod@ligo.org>'


def _parse_unit(parameter):
    try:
        unit = parameter["unit_en"]
    except KeyError:
        return
    if unit in UNITS:
        return UNITS[unit]
    return unit


@read_with_columns
@read_with_selection
def fetch_catalog(catalog, host=DEFAULT_GWOSC_URL):
    catalog = download_catalog(catalog, host=host)
    data = catalog["data"]
    parameters = catalog["parameters"]

    # unpack the catalogue data
    rows = []
    for event, plist in data.items():
        rows.append([event] + [plist[p]["best"] for p in parameters])
    names = ["name"] + list(parameters.keys())
    tab = EventTable(
        rows=rows,
        names=names,
        meta={
            "catalog": catalog,
            "host": host,
        },
    )

    # add units
    for name, parameter in parameters.items():
        unit = _parse_unit(parameter)
        tab[name].unit = unit

    return tab
