import hashlib
import hmac
import json
from uuid import UUID

from octokit_routes import webhook_names


def valid_signature(headers, payload, secret):
    encoding = "utf-8"
    algo, sig = headers.get("X-Hub-Signature").split("=")
    digest = hmac.new(secret.encode(encoding), payload.encode(encoding), getattr(hashlib, algo)).hexdigest()
    return hmac.compare_digest(sig.encode(encoding), digest.encode(encoding))


def valid_guid(guid):
    try:
        return str(UUID(guid)) == guid
    except ValueError:
        return False


def valid_event(event, events):
    return event in webhook_names or "*" in webhook_names


def valid_user_agent(ua):
    return ua.startswith("GitHub-Hookshot/")


def valid_headers(headers, events, verify_user_agent):
    if not valid_guid(headers.get("X-GitHub-Delivery")):
        return False
    if not valid_event(headers.get("X-GitHub-Event"), events):
        return False
    if verify_user_agent and not valid_user_agent(headers.get("User-Agent", "")):
        return False
    return True


def verify(headers, payload, secret, events=None, verify_user_agent=False, return_app_id=False):
    if not valid_headers(headers, events, verify_user_agent):
        return False
    validity = valid_signature(headers, payload, secret)
    if validity and return_app_id and headers.get("X-GitHub-Event") == "ping":
        return json.loads(payload).get("hook").get("app_id")
    return validity
