import numpy as np
from . import nefis
from contextlib import contextmanager
import six

# utilities to grab some data from the process database.
# since the process database is specific to an installation/version,
# and scenarios already carry around paths to their installation,
# ProcessDB requires a scenario in order to find the appropriate
# database files, or explicit paths
class SubstanceDef(object):
    pass

class ProcessDB(object):
    def __init__(self,scenario=None,proc_dat=None,proc_def=None,proc=None):
        self.scenario=scenario # may be None

        if not (proc_dat and proc_def):
            if not proc:
                proc=self.scenario.proc_path
            proc_dat=proc +".dat"
            proc_def=proc +".def"
            
        self.proc_dat=proc_dat
        self.proc_def=proc_def
        
    @contextmanager
    def nef(self):
        nef=nefis.Nefis(self.proc_dat,self.proc_def)
        yield nef
        nef.close()

    def p2_idx_by_item_id(self,subst):
        with self.nef() as db:
            p2_items=db['TABLE_P2'].getelt('ITEM_ID',[0])

        for i in range(len(p2_items)):
            # py3 - have to be careful of bytes vs. str
            p2_item=p2_items[i]
            if six.PY3:
                p2_item=p2_item.decode()
            if p2_item.strip().lower() == subst.lower():
                return i
        return None

    def substance_by_id(self,subst):
        idx=self.p2_idx_by_item_id(subst)
        if idx is None:
            return None

        sub=SubstanceDef()

        with self.nef() as db:
            for elt in ['ITEM_ID','ITEM_NM','UNIT','DEFAULT','AGGREGA','DISAGGR',
                        'GROUPID','SEG_EXC','WK']:
                val=db['TABLE_P2'].getelt(elt,[0,idx])
                # old way:
                #if np.issubdtype(str,val.dtype):
                #    val=str(val.item().strip())
                #else:
                #    val=val.item()
                val=val.item()
                if six.PY3 and isinstance(val,bytes):
                    val=val.decode()
                if isinstance(val,str):
                    val=val.strip()

                setattr(sub,elt.lower(),val)
        return sub


import numpy as np
from . import nefis
from contextlib import contextmanager
import six

# utilities to grab some data from the process database.
# since the process database is specific to an installation/version,
# and scenarios already carry around paths to their installation,
# ProcessDB requires a scenario in order to find the appropriate
# database files, or explicit paths
class SubstanceDef(object):
    pass

class ProcessDB(object):
    def __init__(self,scenario=None,proc_dat=None,proc_def=None,proc=None):
        self.scenario=scenario # may be None

        if not (proc_dat and proc_def):
            if not proc:
                proc=self.scenario.proc_path
            proc_dat=proc +".dat"
            proc_def=proc +".def"
            
        self.proc_dat=proc_dat
        self.proc_def=proc_def
        
    @contextmanager
    def nef(self):
        nef=nefis.Nefis(self.proc_dat,self.proc_def)
        yield nef
        nef.close()

    def p2_idx_by_item_id(self,subst):
        with self.nef() as db:
            p2_items=db['TABLE_P2'].getelt('ITEM_ID',[0])

        for i in range(len(p2_items)):
            # py3 - have to be careful of bytes vs. str
            p2_item=p2_items[i]
            if six.PY3:
                p2_item=p2_item.decode()
            if p2_item.strip().lower() == subst.lower():
                return i
        return None

    def substance_by_id(self,subst):
        idx=self.p2_idx_by_item_id(subst)
        if idx is None:
            return None

        sub=SubstanceDef()

        with self.nef() as db:
            for elt in ['ITEM_ID','ITEM_NM','UNIT','DEFAULT','AGGREGA','DISAGGR',
                        'GROUPID','SEG_EXC','WK']:
                val=db['TABLE_P2'].getelt(elt,[0,idx])
                # old way:
                #if np.issubdtype(str,val.dtype):
                #    val=str(val.item().strip())
                #else:
                #    val=val.item()
                val=val.item()
                if six.PY3 and isinstance(val,bytes):
                    val=val.decode()
                if isinstance(val,str):
                    val=val.strip()

                setattr(sub,elt.lower(),val)
        return sub


# utilities to grab some data from the process database. # since the process database is specific to an installation/version, # and scenarios already carry around paths to their installation, # ProcessDB requires a scenario in order to find the appropriate # database files, or explicit paths # may be None # py3 - have to be careful of bytes vs. str # old way: #if np.issubdtype(str,val.dtype): #    val=str(val.item().strip()) #else: #    val=val.item()