from __future__ import absolute_import
from reflex import RecipeParameter, FitsFile

_ptypes = dict(file=str, list=str, string=str,
               float=float, int=int,
               bool=lambda x: True if x.lower() == 'true' else False)

class VisirParameter:

    def __init__(self, recipe, name, type,
                 description="", display_name=None,
                 options=[]):
        if type not in _ptypes:
            raise ValueError('%s is invalid type' % type)
        if type == 'list' and not options:
            raise ValueError('List parameter needs set of options')
        self.recipe = recipe
        self.display_name = name if not display_name else display_name
        self.name = name
        self.type = type
        self.description = description
        self.options = options

    @staticmethod
    def to_native(ptype, value):
        if not isinstance(value, basestring):
            return value
        if ptype in _ptypes:
            return _ptypes[ptype](value)
        return str(value)

    @staticmethod
    def to_string(ptype, value):
        if ptype == 'bool':
            return 'TRUE' if value else 'FALSE'
        return str(value)

def parseSop(sop):
    """
    remove when in reflex.py
    """
    retVal = list()
    sop_splitted = sop.split(',')
    for parameter in sop_splitted:
        param_recipe = parameter.partition('=')[0].partition(':')[0]
        param_name = parameter.partition('=')[0].partition(':')[2]
        param_value = parameter.partition('=')[2]
        p = RecipeParameter(param_recipe, param_name, "", "")
        p.value = param_value
        retVal.append(p)
    return retVal


try:
    from reflex import parseSof
except:
    # copy to avoid hard pyfits dependency
    def parseSof(sof):
        """
        parses the SoF passed by the PythonActor to 
        a list of FitsFile objects
        """
        retVal = list()
        dataset = sof[:sof.index('|')]
        only_sof = sof[sof.index('|')+1:]
        if len(only_sof) == 0 : 
          return retVal, dataset
        sof_splitted = only_sof.split(',')
        for frame in sof_splitted:
            name     = frame[0:frame.find(";")]
            category = frame[(frame.find(";")+1):(frame.rfind(";"))]
            purpose  = frame[(frame.rfind(";"))+1:]
            retVal.append(FitsFile(name, category, purpose))
        return retVal, dataset


def serialize_par(par):
    return "%s:%s=%s" % (par.recipe, par.name, str(par.value))


def join_sop(parlist):
    return ",".join((serialize_par(p) for p in parlist))


def serialize_fits(fits):
    return "%s;%s;%s" % (fits.name, fits.category, "")#fits.purpose)


def join_sof(fitslist, dataset):
    s = dataset + "|"
    s += ",".join((serialize_fits(f) for f in fitslist))
    return s

