# =============================================================================
# OWSLib. Copyright (C) 2012 Jachym Cepicky
#
# Contact email: jachym.cepicky@gmail.com
#
# =============================================================================

from owslib.crs import Crs

from urllib import urlencode
import logging

try:
    hdlr = logging.FileHandler('/tmp/owslibwfs.log')
except:
    import tempfile
    f=tempfile.NamedTemporaryFile(prefix='owslib.wfs-', delete=False)
    hdlr = logging.FileHandler(f.name)

log = logging.getLogger(__name__)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
log.addHandler(hdlr)
log.setLevel(logging.DEBUG)

class WebFeatureService_:
    """Base class for WebFeatureService implementations"""

    def getBBOXKVP (self,bbox,typename):
        """Formate bounding box for KVP request type (HTTP GET)

        @param bbox: (minx,miny,maxx,maxy[,srs])
        @type bbox: List
        @param typename:  feature name 
        @type typename: String
        @returns: String properly formated according to version and
            coordinate reference system
        """
        srs = None

        # srs of the bbox is specified in the bbox as fifth paramter
        if len(bbox) == 5:
            srs = self.getSRS(bbox[4],typename[0])
        # take default srs
        else:
            srs = self.contents[typename[0]].crsOptions[0]

        # 1.1.0 and 2.0.0 have same encoding
        if self.version in ["1.1.0","2.0.0"]:

            # format bbox parameter
            if srs.encoding == "urn" :
                    if srs.axisorder == "yx":
                        return "%s,%s,%s,%s,%s" % \
                            (bbox[1],bbox[0],bbox[3],bbox[2],srs.getcodeurn())
                    else:
                        return "%s,%s,%s,%s,%s" % \
                        (bbox[0],bbox[1],bbox[2],bbox[3],srs.getcodeurn())
            else:
                return "%s,%s,%s,%s,%s" % \
                        (bbox[0],bbox[1],bbox[2],bbox[3],srs.getcode())
        # 1.0.0
        else:
            return "%s,%s,%s,%s,%s" % \
                    (bbox[0],bbox[1],bbox[2],bbox[3],srs.getcode())

    def getSRS(self,srsname,typename):
        """Returns None or Crs object for given name

        @param typename:  feature name 
        @type typename: String
        """
        if type(srsname) == type(""):
            srs = Crs(srsname)
        else:
            srs = srsname

        srss = map(lambda crs: crs.getcodeurn(),
                self.contents[typename].crsOptions)

        for s in srss:
            s = Crs(s)
            if srs.authority == s.authority and\
                    srs.code == s.code:
                if s.version and srs.version:
                    if s.version  == srs.version:
                        idx = srss.index(s.getcodeurn())
                        return self.contents[typename].crsOptions[idx]
                else:
                    idx = srss.index(s.getcodeurn())
                    return self.contents[typename].crsOptions[idx]
        return None

    def getGETGetFeatureRequest(self, typename=None, filter=None, bbox=None, featureid=None,
                   featureversion=None, propertyname=None, maxfeatures=None,storedQueryID=None, storedQueryParams={},
                   method='Get'):
        """Formulate proper GetFeature request using KVP encoding
        ----------
        typename : list
            List of typenames (string)
        filter : string 
            XML-encoded OGC filter expression.
        bbox : tuple
            (left, bottom, right, top) in the feature type's coordinates == (minx, miny, maxx, maxy)
        featureid : list
            List of unique feature ids (string)
        featureversion : string
            Default is most recent feature version.
        propertyname : list
            List of feature property names. '*' matches all.
        maxfeatures : int
            Maximum number of features to be returned.
        method : string
            Qualified name of the HTTP DCP method to use.

        There are 3 different modes of use

        1) typename and bbox (simple spatial query)
        2) typename and filter (==query) (more expressive)
        3) featureid (direct access to known features)
        """

        base_url = self.getOperationByName('GetFeature').methods[method]['url']
        base_url = base_url if base_url.endswith("?") else base_url+"?"
            
        request = {'service': 'WFS', 'version': self.version, 'request': 'GetFeature'}
        
        # check featureid
        if featureid:
            request['featureid'] = ','.join(featureid)
        elif bbox:
            request['bbox'] = self.getBBOXKVP(bbox,typename)
        elif filter:
            request['query'] = str(filter)
        if typename:
            typename = [typename] if type(typename) == type("") else typename
            request['typename'] = ','.join(typename)
        if propertyname: 
            request['propertyname'] = ','.join(propertyname)
        if featureversion: 
            request['featureversion'] = str(featureversion)
        if maxfeatures: 
            request['maxfeatures'] = str(maxfeatures)
        if storedQueryID: 
            request['storedQuery_id']=str(storedQueryID)
            for param in storedQueryParams:
                request[param]=storedQueryParams[param]
                
        data = urlencode(request)

        return base_url+data
