# -*- coding: utf-8 -*-
"""Module to check PySAM versions and correct input keys to new SAM 2 keys.
Created on Mon Feb  3 14:40:42 2020
@author: gbuster
"""
import logging
import importlib
from warnings import warn
from packaging import version
from reV.utilities.exceptions import PySAMVersionError, PySAMVersionWarning
logger = logging.getLogger(__name__)
[docs]
class PySamVersionChecker:
    """Check the PySAM version and modify input keys if required."""
    WIND = {'wind_farm_losses_percent': 'turb_generic_loss'}
    V2_CORRECTION_KEYS = {'windpower': WIND}
    def __init__(self, requirement='2'):
        """
        Parameters
        ----------
        requirement : str
            PySAM version requirement.
        """
        self._requirement = requirement
        self._check_version()
    def _check_version(self, exception=True):
        """Check the PySAM version and raise exception or warning."""
        check = (version.parse(self.pysam_version)
                 < version.parse(self._requirement))
        if check:
            m = ('Bad PySAM version "{}". Requires: "{}".'
                 .format(self.pysam_version, self._requirement))
            if exception:
                logger.error(m)
                raise PySAMVersionError(m)
            else:
                logger.warning(m)
                warn(m, PySAMVersionWarning)
    def _check_inputs(self, tech, parameters):
        """Check PySAM inputs and modify keys to reflect different
        PySAM versions. Currently set to only correct inputs for PySAM v2.
        Parameters
        ----------
        tech : str
            reV-SAM technology string and key to the V2_CORRECTION_KEYS dict
        parameters : dict
            SAM input dictionary.
        Returns
        -------
        parameters : dict
            Updated input parameters dictionary
        """
        if version.parse(self.pysam_version) >= version.parse('2'):
            parameters = self._check_inputs_v2(tech, parameters)
        return parameters
    def _check_inputs_v2(self, tech, parameters):
        """Check PySAM inputs and modify keys to reflect PySAM 2.
        Parameters
        ----------
        tech : str
            reV-SAM technology string and key to the V2_CORRECTION_KEYS dict
        parameters : dict
            SAM input dictionary. Will be checked for valid keys if
            PySAM version > 2.
        Returns
        -------
        parameters : dict
            Updated input parameters dictionary
        """
        corrections = None
        for key, value in self.V2_CORRECTION_KEYS.items():
            if key in tech:
                corrections = value
                break
        if corrections is not None:
            for key in corrections:
                if key in parameters:
                    new_key = corrections[key]
                    parameters[new_key] = parameters.pop(key)
                    m = ('It appears old SAM v1 keys are being used. '
                         'Updated key "{}" to "{}".'.format(key, new_key))
                    logger.warning(m)
                    warn(m, PySAMVersionWarning)
        return parameters
    @property
    def pysam_version(self):
        """Get the PySAM distribution version"""
        return importlib.metadata.version("nrel-pysam")
[docs]
    @classmethod
    def run(cls, tech, parameters):
        """Run PySAM version and inputs checker and modify keys to reflect
        PySAM 2 updates.
        Parameters
        ----------
        tech : str
            reV-SAM technology string and key to the V2_CORRECTION_KEYS dict
        parameters : dict
            SAM input dictionary. Will be checked for valid keys if
            PySAM version > 2.
        Returns
        -------
        parameters : dict
            Updated input parameters dictionary
        """
        x = cls()
        parameters = x._check_inputs(tech, parameters)
        return parameters