import os
import requests
from pymacaroons import Macaroon
from urllib.parse import urlparse

DASHBOARD_API = os.getenv(
    'DASHBOARD_API',
    "https://dashboard.snapcraft.io/dev/api/",
)
LOGIN_URL = os.getenv(
    'LOGIN_URL',
    "https://login.ubuntu.com",
)


def get_authorization_header(root, discharge):
    """
    Bind root and discharge macaroons and return the authorization header.
    """

    bound = Macaroon.deserialize(root).prepare_for_request(
        Macaroon.deserialize(discharge)
    )

    return 'Macaroon root={}, discharge={}'.format(root, bound.serialize())


def is_authenticated(session):
    """
    Checks if the user is authenticated from the session
    Returns True if the user is authenticated
    """
    return (
        'openid' in session and
        'macaroon_discharge' in session and
        'macaroon_root' in session
    )


def empty_session(session):
    """
    Empty the session, used to logout.
    """
    session.pop('macaroon_root', None)
    session.pop('macaroon_discharge', None)
    session.pop('openid', None)


def get_caveat_id(root):
    """
    Returns the caveat_id generated by the SSO
    """
    location = urlparse(LOGIN_URL).hostname
    caveat, = [
        c for c in Macaroon.deserialize(root).third_party_caveats()
        if c.location == location
    ]

    return caveat.caveat_id


def request_macaroon():
    """
    Request a macaroon from dashboard.
    Returns the macaroon.
    """
    url = ''.join([
        DASHBOARD_API,
        'acl/',
    ])
    response = requests.request(
        url=url,
        method='POST',
        json={
            'permissions': [
                'package_access',
                'package_upload',
                'edit_account'
            ]
        },
        headers={
            'Accept': 'application/json, application/hal+json',
            'Content-Type': 'application/json',
            'Cache-Control': 'no-cache',
        }
    )

    return response.json()['macaroon']


def get_refreshed_discharge(discharge):
    """
    Get a refresh macaroon if the macaroon is not valid anymore.
    Returns the new discharge macaroon.
    """
    url = ''.join([
        LOGIN_URL,
        '/api/v2/tokens/refresh',
    ])
    response = requests.request(
        url=url,
        method='POST',
        json={'discharge_macaroon': discharge},
        headers={
            'Accept': 'application/json, application/hal+json',
            'Content-Type': 'application/json',
            'Cache-Control': 'no-cache',
        }
    )

    return response.json()['discharge_macaroon']


def is_macaroon_expired(headers):
    """
    Returns True if the macaroon needs to be refreshed from
    the header response.
    """
    return headers.get('WWW-Authenticate') == (
            'Macaroon needs_refresh=1')
