import popen2
import sys
import site_conf
import os

from ReplicaCatalog import ReplicaCatalog
from Log import Log
import httplib

class ReplicaFinder:

    def __init__(self, logfile):
        self.log = logfile

    def findLRCs(self, sites):

        locs = []
        for id in sites:
            if id[:4] != 'http' and id[:4] != 'file': # fake lrc
                locs.append((id, 'FAKELRC'))
                continue
            if id[:4] == 'file':
                try:
                    locs.append((id, open(id[5:]).read().strip()))
                except IOError, e:
                    self.log.logError('Error: Cant open file with LRC information: '+str(e))
                else:
                    self.log.logDebug('Using LRC '+id)
                continue
            
            url = id[id.find('://')+3:]
            c = httplib.HTTPConnection(url[:url.find('/')])
            if url[-13:] != '/lrc/endpoint': url += '/lrc/endpoint'

            try:
                c.request("GET", url[url.find('/'):])
                r = c.getresponse()
            except Exception, e:
                self.log.logError('Error with GET request to %s: %s' % (str(url), str(e)))
                continue
            
            if r.status == 302:
                sites.append(r.getheader("Location"))
                c.close()
                continue
            elif r.status == 200:
                endpoint = r.read().strip()
                if endpoint.find('error') != -1 or endpoint.find('Error') != -1:
                    self.log.logError("Bad endpoint at %s: %s" % (str(url), endpoint))
                    continue
                locs.append( (id, endpoint) )
            elif r.status == 404:
                self.log.logError("Can't locate endpoint at %s" % str(url))
            c.close()
        return locs

    def findSURLs(self, guids, sites):
        """Resolve SURLs from list of sites. Filters query to close
        sites only. Order of sites on list corresponds to the order
        used for querying the LRC."""

        locs = self.findLRCs(sites)

        files = {}

        for site, lrc in locs:
            if site.find('cpt.uio.no') != -1 or lrc == None:
                self.log.logError("Find lrc endpoint %s at site %s...skipping" %(lrc, site))
                continue            

            if lrc == 'FAKELRC':
                for guid in guids:
                    finfo = {}
                    finfo['pfns'] = [('FAKEREPLICA:'+guid,)]
                    finfo['fsize'] = '0'
                    finfo['md5sum'] = '0'
                    files[guid] = finfo
                continue

            # check an xml catalog exists. If not the replica catalog
            # crashes with seg fault.
            if lrc.find('xmlcatalog_file:') != -1:
                file = lrc.split(':')[1]
                if not os.path.exists(file):
                    self.log.logError("Error: xml catalog file not found: %s" % file)
                    continue

            if lrc.find('lfccatalog') != -1:

	        child = popen2.Popen4('python ReplicaCatalog.py querySURLs %s' % lrc)
        	r = child.fromchild
	        w = child.tochild
	       	for guid in guids: w.write('guid:%s\n' % guid)
	        w.close()
	        l = r.readline()
	        while l.find('START') == -1:
	            l = r.readline()
	        lrcfiles = eval(r.readline())
	        r.close()
	        child.wait()
            else:
                rc = ReplicaCatalog(lrc, self.log)

                lrcfiles = rc.findFilesQuery(guids)

            for guid in guids:
                if not guid in lrcfiles:
                    continue

                if guid in files: # append surls to those already there
                    files[guid]['pfns'].extend(lrcfiles[guid]['pfns'])
                else:
                    files[guid] = lrcfiles[guid]

        return files