import os
import sys
import base64

from django.db.models import F, Q
from xos.config import Config
from observer.syncstep import SyncStep
from core.models import Service
from hpc.models import ServiceProvider, ContentProvider, CDNPrefix, OriginServer
from util.logger import Logger, logging

# hpclibrary will be in steps/..
parentdir = os.path.join(os.path.dirname(__file__),"..")
sys.path.insert(0,parentdir)

from hpclib import HpcLibrary

logger = Logger(level=logging.INFO)

class SyncOriginServer(SyncStep, HpcLibrary):
    provides=[OriginServer]
    requested_interval=0

    def __init__(self, **args):
        SyncStep.__init__(self, **args)
        HpcLibrary.__init__(self)

    def fetch_pending(self, deleted):
        #self.consistency_check()

        return SyncStep.fetch_pending(self, deleted)

    def consistency_check(self):
        # set to true if something changed
        result=False

        # sanity check to make sure our PS objects have CMI objects behind them
        all_ors_ids = [x["origin_server_id"] for x in self.client.onev.ListAll("OriginServer")]
        for ors in OriginServer.objects.all():
            if (ors.origin_server_id is not None) and (ors.origin_server_id not in all_ors_ids):
                # we have an origin server ID, but it doesn't exist in the CMI
                # something went wrong
                # start over
                logger.info("origin server %s was not found on CMI" % ors.origin_server_id)
                ors.origin_server_id=None
                ors.save()
                result = True

        return result

    def sync_record(self, ors):
        logger.info("sync'ing origin server %s" % str(ors))

        if (not ors.contentProvider) or (not ors.contentProvider.content_provider_id):
            return

        cpid = ors.contentProvider.content_provider_id

        # validation requires URL start with http://
        url = ors.url
        if not url.startswith("http://"):
            url = "http://" + url

        ors_dict = {"authenticated_content": ors.authenticated, "zone_redirects": ors.redirects, "content_provider_id": cpid, "url": url, "service_type": "HyperCache", "caching_type": "Optimistic", "description": ors.description}

        #print os_dict

        if not ors.origin_server_id:
            id = self.client.onev.Create("OriginServer", ors_dict)
            ors.origin_server_id = id
        else:
            self.client.onev.Update("OriginServer", ors.origin_server_id, ors_dict)

        # ... something breaks (analytics) if the URL starts with http://, so we
        # change it in cob after we added it via onev.
        url = url[7:]
        self.client.cob.UpdateContent(ors.origin_server_id, {"url": url})

        ors.silent = True
        ors.save()

    def delete_record(self, m):
        if m.origin_server_id is not None:
            self.client.onev.Delete("OriginServer", m.origin_server_id)
