#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#   Copyright (C) 2020 Oslandia <infos@oslandia.com>
#
#   This file is a piece of free software; you can redistribute it and/or
#   modify it under the terms of the GNU Library General Public
#   License as published by the Free Software Foundation; either
#   version 2 of the License, or (at your option) any later version.
#
#   This library 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
#   Library General Public License for more details.
#   You should have received a copy of the GNU Library General Public
#   License along with this library; if not, see <http://www.gnu.org/licenses/>.
#

AVAILABLE_UNITS = {
    "-": ["-"],
    "m3/s": ["m3/s"],
    "kg/m³": [
        "kg/L",
        "g/L",
        "mg/L",
        "µg/L",
        "kg/m³",
        "g/m³",
        "mg/m³",
        "µg/m³",
        "GBq/L",
        "MBq/L",
        "kBq/L",
        "Bq/L",
        "mBq/L",
        "µBq/L",
        "GBq/m³",
        "MBq/m³",
        "kBq/m³",
        "Bq/m³",
        "mBq/m³",
        "µBq/m³",
    ],
    "m": ["nm", "µm", "mm", "cm", "m", "km"],
    "m³": ["mm³", "L"],
    "g": ["µg", "mg", "g", "kg", "Mg"],
    "N.m": ["N.mm", "N.m"],
    "Pa": ["Pa", "hPa", "kPa", "N/m²", "kg/m/s²"],
    "°C": ["°C"],
    "Bq/kg": ["Bq/kg", "Bq/g", "Bq/mg", "Bq/µg", "µBq/kg", "mBq/kg", "kBq/kg", "MBq/kg", "GBq/kg"],
    "m/s": ["m/s", "m/an", "cm/j"],
    "pH": ["pH"],
    "S/m": ["S/m"],
}


def unitConversionFactor(sourceUnit, targetUnit, specificActivity=0.0):
    """ Return conversion factor between two units

    :param sourceUnit: sourceUnit
    :type sourceUnit: string
    :param targetUnit: targetUnit
    :type targetUnit: string
    :param specificActivity: specificActivity
    :type specificActivity: float

    :return: factor
    :rtype: float
    """
    if sourceUnit == targetUnit:
        return 1  # takes care of the adimentionnal case

    units_conversion_factors = {
        # Debit
        u"m³/s": {u"m³/s": 1.0},
        # Concentration
        u"kg/m³": {
            u"kg/L": 1e-3,
            u"g/L": 1.0,
            u"mg/L": 1e3,
            u"µg/L": 1e6,
            u"kg/m³": 1.0,
            u"g/m³": 1e3,
            u"mg/m³": 1e6,
            u"µg/m³": 1e9,
            u"GBq/L": specificActivity * 1e-9 * 1e-3,
            u"MBq/L": specificActivity * 1e-6 * 1e-3,
            u"kBq/L": specificActivity * 1e-3 * 1e-3,
            u"Bq/L": specificActivity * 1e-3,
            u"mBq/L": specificActivity * 1e3 * 1e-3,
            u"µBq/L": specificActivity * 1e6 * 1e-3,
            u"GBq/m³": specificActivity * 1e-9,
            u"MBq/m³": specificActivity * 1e-6,
            u"kBq/m³": specificActivity * 1e-3,
            u"Bq/m³": specificActivity,
            u"mBq/m³": specificActivity * 1e3,
            u"µBq/m³": specificActivity * 1e6,
        },
        # Metric
        u"m": {u"nm": 1e9, u"µm": 1e6, u"mm": 1e3, u"cm": 1e2, u"m": 1.0, u"km": 1e-3},
        # Volume
        u"m³": {u"mm³": 1e9, u"L": 1e-3},
        # Weight
        u"g": {u"µg": 1e6, u"mg": 1e3, u"g": 1.0, u"kg": 1e-3, u"Mg": 1e-6},
        # Torque
        u"N.m": {u"N.mm": 1e3, u"N.m": 1.0},
        # Pressure
        u"Pa": {u"Pa": 1.0, u"hPa": 1e-2, u"kPa": 1e-3, u"N/m²": 1.0, u"kg/m/s²": 1.0},
        # Temperature
        u"°C": {u"°C": 1.0},
        u"Bq/kg": {
            u"Bq/kg": 1.0,
            u"Bq/g": 1e-3,
            u"Bq/mg": 1.0e-6,
            u"Bq/µg": 1.0e-9,
            u"µBq/kg": 1e6,
            u"mBq/kg": 1e3,
            u"kBq/kg": 1e-3,
            u"MBq/kg": 1e-6,
            u"GBq/kg": 1.0e-9,
        },
        # Speed
        u"m/s": {u"m/s": 1.0, u"m/an": 365.25 * 24 * 3600, u"cm/j": 100.0 * 24 * 3600},
        # pH
        u"pH": {u"pH": 1.0},
        # Conductivity
        u"S/m": {u"S/m": 1.0},
        # Other
        u"-": {u"-": 1.0},
    }

    if sourceUnit not in units_conversion_factors:
        for k, v in units_conversion_factors.items():
            if sourceUnit in v:
                inverse_factor = 1.0 / v[sourceUnit]
                return inverse_factor * units_conversion_factors[k][targetUnit]

    return units_conversion_factors[sourceUnit][targetUnit]
