# coding: utf-8

"""
This module is used to estimate the Herfindahl-Hirschman Index, or HHI, of
chemical compounds. The HHI is a measure of how geographically confined or
dispersed the elements comprising a compound are. A low HHI is desirable
because it means the component elements are geographically dispersed.

Data/strategy from "Data-Driven Review of Thermoelectric Materials:
Performance and Resource Considerations" by Gaultois et al., published
in Chemistry of Materials (2013).
"""

from __future__ import division
import os
from monty.design_patterns import singleton
from pymatgen import Element, Composition

__author__ = 'Anubhav Jain'
__copyright__ = 'Copyright 2014, The Materials Project'
__version__ = '0.1'
__maintainer__ = 'Anubhav Jain'
__email__ = 'ajain@lbl.gov'
__date__ = 'Oct 27, 2014'

csv_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                        'hhi_data.csv')

@singleton
class HHIModel(object):

    def __init__(self):
        self.symbol_hhip_hhir = {}  # symbol->(HHI_production, HHI reserve)

        with open(csv_path) as f:
            for line in f:
                if line[0] != "#":
                    symbol, hhi_production, hhi_reserve = line.split(',')
                    self.symbol_hhip_hhir[symbol] = (float(hhi_production),
                                                     float(hhi_reserve))

    def _get_hhi_el(self, el_or_symbol):
        """
        Returns the tuple of HHI_production, HHI reserve for a single element only
        """
        if isinstance(el_or_symbol, Element):
            el_or_symbol = el_or_symbol.symbol

        return (self.symbol_hhip_hhir[el_or_symbol][0],
                self.symbol_hhip_hhir[el_or_symbol][1])

    def get_hhi(self, comp_or_form):
        """
        Gets the reserve and production HHI for a compound.

        Args:
            comp_or_form (Composition or String): A Composition or String formula

        Returns:
            A tuple representing the (HHI_production, HHI_reserve)
        """

        try:
            if not isinstance(comp_or_form, Composition):
                comp_or_form = Composition(comp_or_form)

            hhi_p = 0
            hhi_r = 0

            for e in comp_or_form.elements:
                percent = comp_or_form.get_wt_fraction(e)
                dp, dr = self._get_hhi_el(e)
                hhi_p += dp * percent
                hhi_r += dr * percent
            return hhi_p, hhi_r

        except:
            return (None, None)

    def get_hhi_production(self, comp_or_form):
        """
        Gets the production HHI for a compound.

        Args:
            comp_or_form (Composition or String): A Composition or String formula

        Returns:
            The HHI production value
        """
        return self.get_hhi(comp_or_form)[0]

    def get_hhi_reserve(self, comp_or_form):
        """
        Gets the reserve HHI for a compound.

        Args:
            comp_or_form (Composition or String): A Composition or String formula

        Returns:
            The HHI reserve value
        """
        return self.get_hhi(comp_or_form)[1]

    def get_hhi_designation(self, hhi):
        """
        Gets a designation for low, medium, high HHI, as specified in "U.S.
        Department of Justice and the Federal Trade Commission, Horizontal
        merger guidelines; 2010."

        Args:
            hhi (float): HHI value

        Returns:
            The designation as String
        """

        if hhi is None:
            return None

        if 0 <= hhi < 1500:
            return 'low'

        if 1500 <= hhi <= 2500:
            return 'medium'

        if hhi > 2500:
            return 'high'
