#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Adapters for the field names/types returned by the MAST API.

"""

from __future__ import (division, print_function, absolute_import,
                        unicode_literals)

__all__ = ["koi_adapter", "planet_adapter", "star_adapter", "dataset_adapter"]

import logging


class Adapter(object):
    """
    An :class:`Adapter` is a callable that maps a dictionary to another
    dictionary with different keys and specified data types. Missing/invalid
    values will be mapped to ``None``.

    :param parameters:
        A dictionary of mappers. The keys should be the keys that will be in
        the input dictionary and the values should be 2-tuples with the output
        key and the callable type converter.

    """

    def __init__(self, parameters):
        self._parameters = parameters

    def __call__(self, row):
        row = dict(row)
        final = {}
        for longname, (shortname, conv) in self._parameters.items():
            try:
                final[shortname] = conv(row.pop(longname, None))
            except (ValueError, TypeError):
                final[shortname] = None

        for k in row:
            logging.warn("Unrecognized parameter: '{0}'".format(k))

        return final


koi_adapter = Adapter({
    "Kepler ID": ("kepid", int),
    "KOI Name": ("kepoi_name", unicode),
    "KOI Number": ("kepoi", unicode),
    "Kepler Disposition": ("koi_pdisposition", unicode),
    "NExScI Disposition": ("koi_disposition", unicode),
    "RA (J2000)": ("degree_ra", float),
    "Dec (J2000)": ("degree_dec", float),
    "Time of Transit Epoch": ("koi_time0bk", float),
    "Time err1": ("koi_time0bk_err1", float),
    "Time_err2": ("koi_time0bk_err2", float),
    "Period": ("koi_period", float),
    "Period err1": ("koi_period_err1", float),
    "Period err2": ("koi_period_err2", float),
    "Transit Depth": ("koi_depth", float),
    "Depth err1": ("koi_depth_err1", float),
    "Depth err2": ("koi_depth_err2", float),
    "Duration": ("koi_duration", float),
    "Duration err1": ("koi_duration_err1", float),
    "Duration err2": ("koi_duration_err2", float),
    "Ingress Duration": ("koi_ingress", float),
    "Ingress err1": ("koi_ingress_err1", float),
    "Ingress err2": ("koi_ingress_err2", float),
    "Impact Parameter": ("koi_impact", float),
    "Impact Parameter err1": ("koi_impact_err1", float),
    "Impact Parameter err2": ("koi_impact_err2", float),
    "Inclination": ("koi_incl", float),
    "Inclination err1": ("koi_incl_err1", float),
    "Inclination err2": ("koi_incl_err2", float),
    "Semi-major Axis": ("koi_sma", float),
    "Semi-major Axus err1": ("koi_sma_err1", float),
    "Semi-major Axis err2": ("koi_sma_err2", float),
    "Eccentricity": ("koi_eccen", float),
    "Eccentricity err1": ("koi_eccen_err1", float),
    "Eccentricity err2": ("koi_eccen_err2", float),
    "Long of Periastron": ("koi_longp", float),
    "Long err1": ("koi_longp_err1", float),
    "Long err2": ("koi_longp_err2", float),
    "r/R": ("koi_ror", float),
    "r/R err1": ("koi_ror_err1", float),
    "r/R err2": ("koi_ror_err2", float),
    "a/R": ("koi_dor", float),
    "a/R err1": ("koi_dor_err1", float),
    "a/R err2": ("koi_dor_err2", float),
    "Planet Radius": ("koi_prad", float),
    "Planet Radius err1": ("koi_prad_err1", float),
    "Planet Radius err2": ("koi_prad_err2", float),
    "Teq": ("koi_teq", int),
    "Teq err1": ("koi_teq_err1", int),
    "Teq err2": ("koi_teq_err2", int),
    "Teff": ("koi_steff", int),
    "Teff err1": ("koi_steff_err1", int),
    "Teff err2": ("koi_steff_err2", int),
    "log(g)": ("koi_slogg", float),
    "log(g) err1": ("koi_slogg_err1", float),
    "log(g) err2": ("koi_slogg_err2", float),
    "Metallicity": ("koi_smet", float),
    "Metallicity err1": ("koi_smet_err1", float),
    "Metallicity err2": ("koi_smet_err2", float),
    "Stellar Radius": ("koi_srad", float),
    "Stellar Radius err1": ("koi_srad_err1", float),
    "Stellar Radius err2": ("koi_srad_err2", float),
    "Stellar Mass": ("koi_smass", float),
    "Stellar Mass err2": ("koi_smass_err2", float),
    "Stellar Mass err1": ("koi_smass_err1", float),
    "Age": ("koi_sage", float),
    "Age err1": ("koi_sage_err1", float),
    "Age err2": ("koi_sage_err2", float),
    "Provenance": ("koi_sparprov", unicode),
    "Quarters": ("koi_quarters", unicode),
    "Limb Darkening Model": ("koi_limbdark_mod", unicode),
    "Limb Darkening Coeff1": ("koi_ldm_coeff1", float),
    "Limb Darkening Coeff2": ("koi_ldm_coeff2", float),
    "Limb Darkening Coeff3": ("koi_ldm_coeff3", float),
    "Limb Darkening Coeff4": ("koi_ldm_coeff4", float),
    "Transit Number": ("koi_num_transits", int),
    "Max single event sigma": ("koi_max_sngle_ev", float),
    "Max Multievent sigma": ("koi_max_mult_ev", float),
    "KOI count": ("koi_count", int),
    "Binary Discrimination": ("koi_bin_oedp_sig", float),
    "False Positive Bkgnd ID": ("koi_fp_bkgid", unicode),
    "J-band diff": ("koi_fp_djmag", unicode),
    "Comments": ("koi_comment", unicode),
    "Transit Model": ("koi_trans_mod", unicode),
    "Transit Model SNR": ("koi_model_snr", float),
    "Transit Model DOF": ("koi_model_dof", float),
    "Transit Model chisq": ("koi_model_chisq", float),
    "FWM motion signif.": ("koi_fwm_stat_sig", float),
    "gmag": ("koi_gmag", float),
    "gmag err": ("koi_gmag_err", float),
    "rmag": ("koi_rmag", float),
    "rmag err": ("koi_rmag_err", float),
    "imag": ("koi_imag", float),
    "imag err": ("koi_imag_err", float),
    "zmag": ("koi_zmag", float),
    "zmag err": ("koi_zmag_err", float),
    "Jmag": ("koi_jmag", float),
    "Jmag err": ("koi_jmag_err", float),
    "Hmag": ("koi_hmag", float),
    "Hmag err": ("koi_hmag_err", float),
    "Kmag": ("koi_kmag", float),
    "Kmag err": ("koi_kmag_err", float),
    "kepmag": ("koi_kepmag", float),
    "kepmag err": ("koi_kepmag_err", float),
    "Delivery Name": ("koi_delivname", unicode),
    "FWM SRA": ("koi_fwm_sra", float),
    "FWM SRA err": ("koi_fwm_sra_err", float),
    "FWM SDec": ("koi_fwm_sdec", float),
    "FWM SDec err": ("koi_fwm_sdec_err", float),
    "FWM SRAO": ("koi_fwm_srao", float),
    "FWM SRAO err": ("koi_fwm_srao_err", float),
    "FWM SDeco": ("koi_fwm_sdeco", float),
    "FWM SDeco err": ("koi_fwm_sdeco_err", float),
    "FWM PRAO": ("koi_fwm_prao", float),
    "FWM PRAO err": ("koi_fwm_prao_err", float),
    "FWM PDeco": ("koi_fwm_pdeco", float),
    "FWM PDeco err": ("koi_fwm_pdeco_err", float),
    "Dicco MRA": ("koi_dicco_mra", float),
    "Dicco MRA err": ("koi_dicco_mra_err", float),
    "Dicco MDec": ("koi_dicco_mdec", float),
    "Dicco MDec err": ("koi_dicco_mdec_err", float),
    "Dicco MSky": ("koi_dicco_msky", float),
    "Dicco MSky err": ("koi_dicco_msky_err", float),
    "Dicco FRA": ("koi_dicco_fra", float),
    "Dicco FRA err": ("koi_dicco_fra_err", float),
    "Dicco FDec": ("koi_dicco_fdec", float),
    "Dicco FDec err": ("koi_dicco_fdec_err", float),
    "Dicco FSky": ("koi_dicco_fsky", float),
    "Dicco FSky err": ("koi_dicco_fsky_err", float),
    "Dikco MRA": ("koi_dikco_mra", float),
    "Dikco MRA err": ("koi_dikco_mra_err", float),
    "Dikco MDec": ("koi_dikco_mdec", float),
    "Dikco MDec err": ("koi_dikco_mdec_err", float),
    "Dikco MSky": ("koi_dikco_msky", float),
    "Dikco MSky err": ("koi_dikco_msky_err", float),
    "Dikco FRA": ("koi_dikco_fra", float),
    "Dikco FRA err": ("koi_dikco_fra_err", float),
    "Dikco FDec": ("koi_dikco_fdec", float),
    "Dikco FDec err": ("koi_dikco_fdec_err", float),
    "Dikco FSky": ("koi_dikco_fsky", float),
    "Dikco FSky err": ("koi_dikco_fsky_err", float),
    "Last Update": ("rowupdate", unicode),
})

planet_adapter = Adapter({
    "Planet Name": ("kepler_name", unicode),
    "Kepler ID": ("kepid", int),
    "KOI Name": ("kepoi_name", unicode),
    "Alt Name": ("alt_name", unicode),
    "KOI Number": ("koi_number", unicode),  # Just `koi` in API.
    "RA (J2000)": ("degree_ra", float),
    "RA Error": ("ra_err", float),
    "Dec (J2000)": ("degree_dec", float),
    "Dec Error": ("dec_err", float),
    "2mass Name": ("tm_designation", unicode),
    "Planet temp": ("koi_teq", int),
    "Planet Radius": ("koi_prad", float),
    "Transit duration": ("koi_duration", float),
    "Period": ("koi_period", float),
    "Period err1": ("koi_period_err1", float),
    "Ingress Duration": ("koi_ingress", float),
    "Impact Parameter": ("koi_impact", float),
    "Inclination": ("koi_incl", float),
    "Provenance": ("koi_sparprov", unicode),
    "a/R": ("koi_dor", float),
    "Transit Number": ("koi_num_transits", int),
    "Transit Model": ("koi_trans_mod", unicode),
    "Time of transit": ("koi_time0bk", float),
    "Time of transit err1": ("koi_time0bk_err1", float),
    "Transit Depth": ("koi_depth", float),
    "Semi-major Axis": ("koi_sma", float),
    "r/R": ("koi_ror", float),
    "r/R err1": ("koi_ror_err1", float),
    "Age": ("koi_sage", float),
    "Metallicity": ("koi_smet", float),
    "Stellar Mass": ("koi_smass", float),
    "Stellar Radius": ("koi_srad", float),
    "Stellar Teff": ("koi_steff", int),
    "Logg": ("koi_slogg", float),
    "KEP Mag": ("koi_kepmag", float),
    "g Mag": ("koi_gmag", float),
    "r Mag": ("koi_rmag", float),
    "i Mag": ("koi_imag", float),
    "z Mag": ("koi_zmag", float),
    "J Mag": ("koi_jmag", float),
    "H Mag": ("koi_hmag", float),
    "K Mag": ("koi_kmag", float),
    "KOI List": ("koi_list_flag", unicode),
    "Last Update": ("koi_vet_date", unicode),
})

star_adapter = Adapter({
    "Kepler ID": ("kic_kepler_id", int),
    "RA (J2000)": ("kic_degree_ra", float),
    "Dec (J2000)": ("kic_dec", float),
    "RA PM (arcsec/yr)": ("kic_pmra", float),
    "Dec PM (arcsec/yr)": ("kic_pmdec", float),
    "u Mag": ("kic_umag", float),
    "g Mag": ("kic_gmag", float),
    "r Mag": ("kic_rmag", float),
    "i Mag": ("kic_imag", float),
    "z Mag": ("kic_zmag", float),
    "Gred Mag": ("kic_gredmag", float),
    "D51 Mag": ("kic_d51mag", float),
    "J Mag": ("kic_jmag", float),
    "H Mag": ("kic_hmag", float),
    "K Mag": ("kic_kmag", float),
    "Kepler Mag": ("kic_kepmag", float),
    "2MASS ID": ("kic_2mass_id", unicode),
    "2MASS Designation": ("kic_tmid", int),
    "SCP ID": ("kic_scpid", int),
    "Alt ID": ("kic_altid", int),
    "Alt ID Source": ("kic_altsource", int),
    "Star/Gal ID": ("kic_galaxy", int),
    "Isolated/Blend ID": ("kic_blend", int),
    "Var. ID": ("kic_variable", int),
    "Teff (deg K)": ("kic_teff", int),
    "Log G (cm/s/s)": ("kic_logg", float),
    "Metallicity (solar=0.0)": ("kic_feh", float),
    "E(B-V)": ("kic_ebminusv", float),
    "A_V": ("kic_av", float),
    "Radius (solar=1.0)": ("kic_radius", float),
    "Kepmag Source": ("kic_cq", unicode),
    "Photometry Qual": ("kic_pq", int),
    "Astrophysics Qual": ("kic_aq", int),
    "Catalog key": ("kic_catkey", int),
    "Scp Key": ("kic_scpkey", int),
    "Parallax (arcsec)": ("kic_parallax", float),
    "Gal Lon (deg)": ("kic_glon", float),
    "Gal Lat (deg)": ("kic_glat", float),
    "Total PM (arcsec/yr)": ("kic_pmtotal", float),
    "g-r color": ("kic_grcolor", float),
    "J-K color": ("kic_jkcolor", float),
    "g-K color": ("kic_gkcolor", float),
    "RA hours (J2000)": ("kic_ra", float),
})

dataset_adapter = Adapter({
    "Kepler ID": ("ktc_kepler_id", int),
    "Investigation ID": ("ktc_investigation_id", unicode),
    "Pep ID": ("sci_pep_id", int),
    "Dataset Name": ("sci_data_set_name", unicode),
    "Quarter": ("sci_data_quarter", int),
    "Data Release": ("sci_data_rel", int),
    "RA (J2000)": ("sci_ra", float),
    "Dec (J2000)": ("sci_dec", float),
    "Target Type": ("ktc_target_type", unicode),
    "Archive Class": ("sci_archive_class", unicode),
    "Ref": ("refnum", int),
    "Actual Start Time": ("sci_start_time", unicode),
    "Actual End Time": ("sci_end_time", unicode),
    "Release Date": ("sci_release_date", unicode),
    "RA PM": ("kic_pmra", float),
    "Dec PM": ("kic_pmdec", float),
    "U Mag": ("kic_umag", float),
    "G Mag": ("kic_gmag", float),
    "R Mag": ("kic_rmag", float),
    "I Mag": ("kic_imag", float),
    "Z Mag": ("kic_zmag", float),
    "GRed Mag": ("kic_gredmag", float),
    "D51 Mag": ("kic_d51mag", float),
    "J Mag": ("twoMass_jmag", float),
    "H Mag": ("twoMass_hmag", float),
    "K Mag": ("twoMass_kmag", float),
    "KEP Mag": ("kic_kepmag", float),
    "2MASS ID": ("twoMass_2mass_id", unicode),
    "2MASS Designation": ("twoMass_tmid", int),
    "twoMass conflict flag": ("twoMass_conflictFlag", unicode),
    "SCP ID": ("kic_scpid", int),
    "Alt ID": ("kic_altid", int),
    "Alt ID Source": ("kic_altsource", int),
    "Star/Gal ID": ("kic_galaxy", int),
    "Isolated/Blend ID": ("kic_blend", int),
    "Var. ID": ("kic_variable", int),
    "Teff": ("kic_teff", int),
    "Log G": ("kic_logg", float),
    "Metallicity": ("kic_feh", float),
    "E(B-V)": ("kic_ebminusv", float),
    "A_V": ("kic_av", float),
    "Radius": ("kic_radius", float),
    "Kepmag Source": ("kic_cq", unicode),
    "Photometry Qual": ("kic_pq", int),
    "Astrophysics Qual": ("kic_aq", int),
    "Catalog key": ("kic_catkey", int),
    "Scp Key": ("kic_scpkey", int),
    "Parallax": ("kic_parallax", float),
    "Gal Lon": ("kic_glon", float),
    "Gal Lat": ("kic_glat", float),
    "Total PM": ("kic_pmtotal", float),
    "G-R color": ("kic_grcolor", float),
    "J-K color": ("twoMass_jkcolor", float),
    "G-K color": ("twoMass_gkcolor", float),
    "Processing Date": ("sci_generation_date", unicode),
    "crowding": ("sci_crowdsap", float),
    "contamination": ("sci_contamination", float),
    "flux fraction": ("sci_flfrcsap", float),
    "cdpp3": ("sci_Cdpp3_0", float),
    "cdpp6": ("sci_Cdpp6_0", float),
    "cdpp12": ("sci_Cdpp12_0", float),
    "Module": ("sci_module", int),
    "Output": ("sci_output", int),
    "Channel": ("sci_channel", int),
    "Skygroup_ID": ("sci_skygroup_id", int),
    "Condition flag": ("condition_flag", unicode),
})
