# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

mastodon_edge = {
    'color': {
        'color': '#5942d1'
    },
    'title': 'Mastodon Snowflake',
    'label': '🐘'
}
# Mastodon by nature is federated and there are many, many domains hosting instances.
# This list was built from instances.social & https://coxy.co/mastodon/.
mastodon_domains = [
    '101010.pl',
    'anticapitalist.party',
    'appdot.net',
    'astrodon.social',
    'augsburg.social',
    'aus.social',
    'banana.dog',
    'baraag.net',
    'barcelona.social',
    'beach.city',
    'benign.town',
    'berserker.town',
    'bikesare.cool',
    'bitcoinhackers.org',
    'blacktwitter.io',
    'bonn.social',
    'bookwor.ms',
    'bostonmusic.online',
    'brandenburg.social',
    'btc.gdn',
    'catcatnya.com',
    'chilemasto.casa',
    'chinwag.org',
    'chitter.xyz',
    'ciences.social',
    'climatejustice.social',
    'cloudisland.nz',
    'computerfairi.es',
    'cooler.mom',
    'cosmos.social',
    'cuddly.space',
    'cultur.social',
    'cute.is',
    'dads.cool',
    'darmstadt.social',
    'deadinsi.de',
    'democracy.town',
    'demoncore.info',
    'dice.camp',
    'digitalcourage.social',
    'distrotoot.com',
    'dolphin.town',
    'dragon.style',
    'dresden.network',
    'ecoevo.social',
    'econtwitter.net',
    'fandom.ink',
    'federated.press',
    'fediscience.org',
    'fediverse.co.za',
    'fikaverse.club',
    'fosstodon.org',
    'freeradical.zone',
    'fribygda.no',
    'friend.camp',
    'functional.cafe',
    'ghost.cafe',
    'girlcock.club',
    'glaceon.social',
    'glammr.us',
    'glasgow.social',
    'goblin.camp',
    'hachyderm.io',
    'hackers.town',
    'harrystyl.es',
    'hcommons.social',
    'hispagatos.space',
    'history.lol',
    'hyperpla.net',
    'icosahedron.website',
    'im-in.space',
    'indieweb.social',
    'infosec.exchange',
    'interfaith.masto.host',
    'ioc.exchange',
    'ischool.social',
    'jmm.kr',
    'jorts.horse',
    'journa.host',
    'kinky.business',
    'kitch.win',
    'kitty.town',
    'kosmos.social',
    'kpop.social',
    'laserdisc.party',
    'lesbianschool.com',
    'lgbt.io',
    'lgbtqplus.social',
    'liker.social',
    'linernotes.club',
    'livester.net',
    'lonely.town',
    'lor.sh',
    'machteburch.social',
    'magnificentbeardsfan.club',
    'mapstodon.space',
    'mas.to',
    'masthead.social',
    'masto.ai',
    'masto.donte.com.br',
    'masto.pt',
    'masto.social',
    'mastodon.art',
    'mastodon.cloud',
    'mastodon.com.br',
    'mastodon.com.tr',
    'mastodon.design',
    'mastodon.green',
    'mastodon.lol',
    'mastodon.me.uk',
    'mastodon.mg',
    'mastodon.ml',
    'mastodon.nl',
    'mastodon.nu',
    'mastodon.nz',
    'mastodon.nzoss.nz',
    'mastodon.online',
    'mastodon.org.uk',
    'mastodon.radio',
    'mastodon.sandwich.net',
    'mastodon.scot',
    'mastodon.se',
    'mastodon.shenenfa.cn',
    'mastodon.social',
    'mastodon.technology',
    'mastodon.tokyo',
    'mastodon.uno',
    'mastodon.uy',
    'mastodon.vn.ua',
    'mastodon.world',
    'mastodon.xyz',
    'mastodonapp.uk',
    'mastodong.lol',
    'mastodont.cat',
    'mastodontti.fi',
    'mastodos.com',
    'mathstodon.xyz',
    'mathtod.online',
    'matitodon.com',
    'mellified.men',
    'meow.social',
    'metalhead.club',
    'monocles.social',
    'moon.holiday',
    'mpp.community',
    'mstdn.ca',
    'mstdn.es',
    'mstdn.fr',
    'mstdn.io',
    'mstdn.jp',
    'mstdn.mx',
    'mstdn.science',
    'mstdn.social',
    'muenchen.social',
    'nerdculture.de',
    'norden.social',
    'nrw.social',
    'oberpfalz.social',
    'occult.camp',
    'oceanplayground.social',
    'octodon.social',
    'oldbytes.space',
    'oslo.town',
    'osna.social',
    'oval.cc',
    'pawoo.net',
    'peoplemaking.games',
    'photog.social',
    'plush.city',
    'queer.af',
    'queer.garden',
    'queer.party',
    'rage.love',
    'raggedfeathers.com',
    'raru.re',
    'retro.pizza',
    'retro.social',
    'ruby.social',
    'ruhr.social',
    'sanantonio.lol',
    'sartorial.online',
    'saturation.social',
    'savageworlds.social',
    'scholar.social',
    'scicomm.xyz',
    'sfba.social',
    'sinblr.com',
    'skastodon.com',
    'smores.town',
    'snabelen.no',
    'soc.ua-fediland.de',
    'social.cologne',
    'social.coop',
    'social.kyiv.dcomm.net.ua',
    'social.privacytools.io',
    'social.saarland',
    'social.scambi.org',
    'social.seattle.wa.us',
    'sonomu.club',
    'sunbeam.city',
    'switter.at',
    'tabletop.social',
    'tech.lgbt',
    'telescope.garden',
    'tenforward.social',
    'thecabal.xyz',
    'themastodonlife.com',
    'theres.life',
    'thicc.horse',
    'toot.bike',
    'toot.cafe',
    'toot.koeln',
    'toot.si',
    'toot.site',
    'toot.wales',
    'transforthe.win',
    'triangletoot.party',
    'tutoteket.no',
    'twingyeo.kr',
    'TWiT.social',
    'tyrol.social',
    'unbound.social',
    'urbanists.social',
    'uwu.town',
    'vattenkylaren.se',
    'vis.social',
    'vulpine.club',
    'wandering.shop',
    'weirder.earth',
    'writing.exchange',
    'wue.social',
    'xoxo.zone',
    'yesterweb.org'
]


def parse_mastodon_snowflake(unfurl, node):
    # Ref: https://github.com/tootsuite/mastodon/issues/1059
    #      https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/snowflake.rb
    try:
        snowflake = int(node.value)
        seq_data = snowflake & 0xFF
        timestamp = (snowflake >> 16) 

    except Exception as e:
        print(e)
        return

    node.hover = 'Mastodon Snowflakes are time-based IDs similar to those of Twitter Snowflakes. ' \
                 '<a href="https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake.html" ' \
                 'target="_blank">[ref]</a>'

    unfurl.add_to_queue(
        data_type='epoch-milliseconds', key=None, value=timestamp, label=f'Timestamp: {timestamp}',
        hover='The first 16 bits value in a Mastodon Snowflake is a timestamp.',
        parent_id=node.node_id, incoming_edge_config=mastodon_edge)

    unfurl.add_to_queue(
         data_type='integer', key=None, value=seq_data, label=f'Sequence data: {seq_data}',
         hover="The 'sequence data' is intended to be unique within a given millisecond. It is a 2 byte value.",
         parent_id=node.node_id, incoming_edge_config=mastodon_edge)


def run(unfurl, node):
    # Known pattern from mastodon.social site
    if node.data_type == 'url.path.segment':
        # Check if node is a child of a mastodon domain, is an integer, & timestamp would be between 2015-01 and 2030-01
        if any(mastodon_domain in unfurl.find_preceding_domain(node) for mastodon_domain in mastodon_domains) and \
                unfurl.check_if_int_between(node.value, 93065733734400000, 124089536413761540):
            parse_mastodon_snowflake(unfurl, node)
