from google.cloud import scheduler
from .project import ProjectReference
from .exceptions import ProjectReferenceNotDefinedException


class SchedulerUtil:
    """
    Auxiliary class for Google Cloud Scheduler
    """
    CRON_HEADERS = ['X-Appengine-User-Ip', 'X-Appengine-Cron']

    def __init__(self, project=None, project_id=None, location=None):
        self.client = scheduler.CloudSchedulerClient()
        self.project = project if project else ProjectReference(project_id, location)

    def create_job(self, job_def: dict):
        """
        Creates a cron job in Google Cloud Scheduler

        :param job_def: Job defintion. See the link below:
        https://googleapis.dev/python/cloudscheduler/latest/gapic/v1/types.html#google.cloud.scheduler_v1.types.Job
        :raises ProjectReferenceNotDefinedException
        """
        if not self.project:
            raise ProjectReferenceNotDefinedException()

        parent = self.client.location_path(self.project.project_id, self.project.location)

        self.client.create_job(parent, job_def)

    @classmethod
    def is_cron_request(cls, request):
        """
        Verify if a flask request is generated by GCloud Cron Service

        "The X-Appengine-Cron header is set internally by Google App Engine. If your request handler finds
        this header it can trust that the request is a cron request. The X- headers are stripped by App Engine
        when they originate from external sources so that you can trust this header."

        Reference:
        https://cloud.google.com/appengine/docs/standard/python3/scheduling-jobs-with-cron-yaml#validating_cron_requests

        :param request: Flask Response object
        :return:        If the request was created by a google cloud cron job
        """
        headers = dict(t for t in request.headers if t[0] in cls.CRON_HEADERS)

        if set(cls.CRON_HEADERS) == headers.keys():
            return headers['X-Appengine-Cron']

        return False
