import logging
import os
from contextlib import contextmanager
from urllib.parse import urljoin

from etherpad_lite import EtherpadLiteClient, EtherpadException

from django.conf import settings


logger = logging.getLogger(__name__)


@contextmanager
def ignore_ep_exception(msg="", *exceptions):
    try:
        yield
    except exceptions as e:
        logger.error(msg)
        logger.error("%s", e)


def get_ep_client(groupName="fet"):
    epc = None
    group = None

    with ignore_ep_exception("Error connecting to Etherpad", Exception):
        with open(os.path.abspath(settings.ETHERPAD_CLIENT["apikey"]), "r") as f:
            apikey = f.read()
            apikey = apikey.rstrip()
            epc = EtherpadLiteClient(
                base_params={
                    "apikey": apikey,
                },
                base_url=urljoin(settings.ETHERPAD_CLIENT["url"], "api"),
                api_version="1.2.14",
            )

        if settings.ETHERPAD_CLIENT["group"] == "":
            group = epc.createGroupIfNotExistsFor(groupMapper=groupName)
        else:
            group = {"groupID": settings.ETHERPAD_CLIENT["group"]}

    return epc, group


@contextmanager
def ep_client(groupName="fet"):
    epc, group = get_ep_client(groupName)
    if not epc or not group:
        yield None, None
    else:
        with ignore_ep_exception("EtherpadException!!", EtherpadException):
            yield epc, group


def __pad_exists(padID=None):
    if not padID:
        return False

    with ep_client() as (epc, group):
        if not epc or not group:
            return None

        lists = epc.listPads(groupID=group["groupID"])
        if any(str(padID) in s for s in lists["padIDs"]):
            logger.info(f"Pad '{padID}' existiert.")
            return True

    logger.info(f"Pad '{padID}' existiert nicht.")
    return False


def create_pad(padID, text="helloworld"):
    """
    Create a pad if it doesn't exist.

    Return a padID if new pad is created. Otherwise None (when the padID exists already).
    """
    if not __pad_exists(padID=padID):
        with ep_client() as (epc, group):
            if not epc or not group:
                return None

            epc.createGroupPad(groupID=group["groupID"], padName=padID, text=text)
            logger.info(f"neues Pad erzeugt: {padID}")
        return padID

    return None


def get_pad_html(padID):
    text = None
    with ep_client() as (epc, group):
        if not epc or not group:
            return None

        text = epc.getHTML(padID=group["groupID"] + "$" + padID)["html"]
    return text


def set_pad_html(padID, html):
    epc, group = get_ep_client()
    if not epc or not group:
        return None

    epc.setHTML(padID=group["groupID"] + "$" + padID, html=html)
    return html


def get_pad_link(padID):
    if not padID:
        return "#"

    with ep_client() as (epc, group):
        if not epc or not group:
            return "#"

        return urljoin(
            settings.ETHERPAD_CLIENT["exturl"],
            "p/" + group["groupID"] + "$" + str(padID),
        )
