from datetime import datetime

from baton._baton.json import DataObjectJSONEncoder
from baton.api import connect_to_irods_with_baton
from cookiemonster.common.models import Cookie, Enrichment
from cookiemonster.processor.models import EnrichmentLoader
from hgicommon.collections import Metadata
from hgicommon.data_source import register

from hgicookiemonster.context import HgiContext

IRODS_SOURCE = "irods"


def _can_enrich(cookie: Cookie, context: HgiContext) -> bool:
    if cookie.enrichments[-1] != IRODS_SOURCE:
        return True


def _load_enrichment(cookie: Cookie, context: HgiContext) -> Enrichment:
    _irods = connect_to_irods_with_baton(context.config.baton.binaries_location)
    data_object = _irods.data_object.get_by_path(cookie.identifier)
    data_object_as_json = DataObjectJSONEncoder().default(data_object)
    context.slack.post("Added more information about %s from iRODS" % cookie.identifier)
    return Enrichment(IRODS_SOURCE, datetime.now(), Metadata(data_object_as_json))


_enrichment_loader = EnrichmentLoader(_can_enrich, _load_enrichment, priority=0, name=IRODS_SOURCE)
register(_enrichment_loader)
        # https://github.com/wtsi-hgi/cookie-monster/issues/44)
        url = "%s?identifier=%s" % (self.api_location, quote(identifier))
        request = Request(url, None, {"Accept": "application/json"})
        cookie_as_json = json.loads(urlopen(request).read().decode("utf-8"))
        # FIXME: There should be a `CookieJSONDecoder`
        cookie = Cookie(identifier)
        for enrichment in _CookieLoadingDict._ENRICHMENT_JSON_DECODER.decode_parsed(cookie_as_json["enrichments"]):
            assert isinstance(enrichment, Enrichment)
            cookie.enrich(enrichment)
        return cookie


def read_not_ignored(cookie_monster_api_location: str, not_ignored_list_location: str=NOT_IGNORED_LIST_LOCATION) \
        -> Dict[str, Cookie]:
    """
    Gets not ignored cookies in a dict where the keys are the identifiers of the ignored cookies and the values are the
    cookies themselves (loaded from the API on-the-fly).
    :param cookie_monster_api_location: the location of the Cookie Monster API
    :param not_ignored_list_location: the location of the not ignored list to read
    :return: not ignored cookies
    """
    identifiers = []    # type: List[str]
    with open(not_ignored_list_location, "r") as file:
        for line in file:
            identifiers.append(line.strip())
    return _CookieLoadingDict(cookie_monster_api_location, identifiers)


_rule = Rule(_matches, _action, NOT_IGNORED_RULE_ID, NOT_IGNORED_RULE_PRIORITY)
register(_rule)