"""
Updates IRR objects in RIPE for the CCCamp IX.

This, given a mntner password and a list of ASNs taking part in the IXP will
ensure the right IRR objects are present:

 - an aut-num containing import/export RPSL rules
 - an as-set containing all member ASs.


"""

import difflib
import string
import sys
import time

import requests


class IRRObject:
    """An IRR object from RIPE."""
    TYPE = None
    def __init__(self, fields=None):
        self.fields = fields or []

    def add(self, k, v):
        self.fields.append((k, v))

    def render(self):
        """Render to IRR format."""
        return '\n'.join('{:16s}{}'.format(k+":", v) for k, v in self.fields) + "\n"

    @classmethod
    def from_ripe(cls, v):
        """Download this object from the RIPE REST API."""
        if cls.TYPE is None:
            raise Exception('cannot fetch untyped IRRObject')

        r = requests.get('https://rest.db.ripe.net/ripe/{}/{}.json'.format(cls.TYPE, v))
        d = r.json()

        obj = d['objects']['object'][0]
        assert obj['type'] == cls.TYPE
        assert obj['primary-key']['attribute'][0]['value'] == v

        attrs = obj['attributes']['attribute']

        fields = []
        for attr in attrs:
            # Skip metadata.
            if attr['name'] in ('created', 'last-modified'):
                continue
            fields.append((attr['name'], attr['value']))

        return cls(fields)

    def send_to_ripe(self, password):
        """Update this object (or create new) in RIPE using the SyncUpdates API."""
        res = self.render()
        res += 'password:       {}\n'.format(password)

        data = {
            'DATA': res,
        }
        r = requests.post('http://syncupdates.db.ripe.net/', files=data)
        res = r.text
        if 'Modify SUCCEEDED' not in res:
            print(res)
            raise Exception("Unexpected result from RIPE syncupdates")


banner = [
    ('remarks', r".--------------------------------------."),
    ('remarks', r"|   _                         _    __  |"),
    ('remarks', r"|  | |__   __ _ _ ____      _| |_ / _| |"),
    ('remarks', r"|  | '_ \ / _` | '_ \ \ /\ / / __| |_  |"),
    ('remarks', r"|  | |_) | (_| | |_) \ V  V /| |_|  _| |"),
    ('remarks', r"|  |_.__/ \__, | .__(_)_/\_/  \__|_|   |"),
    ('remarks', r"|         |___/|_|                     |"),
    ('remarks', r"|--------------------------------------|"),
    ('remarks', r"|  CCCamp2019 Internet Exchange Point  |"),
    ('remarks', r"'--------------------------------------'"),
    ('remarks', r''),
    ('remarks', r'// 21. - 25. August 2019'),
    ('remarks', r'// Ziegeleipark Mildenberg, Zehdenick, Germany, Earth, Milky Way'),
    ('remarks', r'// Join us: https://bgp.wtf/cccamp19'),
    ('remarks', r''),
]


class IXPAutNum(IRRObject):
    """An aut-num (AS) object."""
    TYPE = 'aut-num'
    @classmethod
    def make_for_members(cls, members):
        fields = [
            ('aut-num', 'AS208521'),
            ('as-name', 'BGPWTF-CCCAMP19-IX'),
        ] + banner + [
            ('remarks', '// Current members:'),
        ]

        for member in sorted(list(members)):
            fields.append(('import', 'from {} accept {}'.format(member, member)))
            fields.append(('export', 'to {} announce AS-CCCAMP19-IX'.format(member)))

        fields += [
            ('remarks', ''),
            ('remarks', '// Abuse: noc@hackerspace.pl'),
            ('org', 'ORG-SH103-RIPE'),
            ('admin-c', 'HACK2-RIPE'),
            ('tech-c', 'HACK2-RIPE'),
            ('status', 'ASSIGNED'),
            ('mnt-by', 'RIPE-NCC-END-MNT'),
            ('mnt-by', 'BGPWTF-AUTOMATION'),
            ('mnt-by', 'pl-hs-1-mnt'),
            ('source', 'RIPE'),
        ]

        return cls(fields)


class ASSet(IRRObject):
    """An as-set object."""
    TYPE = 'as-set'
    @classmethod
    def make_for_members(cls, members):
        fields = [
            ('as-set', 'AS-CCCAMP19-IX'),
            ('admin-c', 'HACK2-RIPE'),
        ] + banner + [
            ('remarks', '// Current members:'),
        ]

        for member in sorted(list(members)):
            fields.append(('members', member))

        fields += [
            ('remarks', ''),
            ('remarks', '// Abuse: noc@hackerspace.pl'),
            ('tech-c', 'HACK2-RIPE'),
            ('mnt-by', 'BGPWTF-AUTOMATION'),
            ('mnt-by', 'pl-hs-1-mnt'),
            ('source', 'RIPE'),
        ]

        return cls(fields)


def sync(want, got, password, force):
    """Sync an object if there is a diff to its current state."""
    wantr = want.render().split('\n')
    gotr = got.render().split('\n')

    d = list(difflib.unified_diff(gotr, wantr, fromfile='got', tofile='want'))
    fields_diff = set()
    for dd in d:
        if dd.startswith('---'):
            continue
        if dd.startswith('+++'):
            continue
        if not dd.startswith('+') and not dd.startswith('-'):
            continue

        field = dd[1:].split(':')[0]
        fields_diff.add(field)

    # We ignore remarks field changes, because the RIPE API returns us them always
    # mangled (with spaces missing in the ASCII art).
    if list(fields_diff) == ['remarks'] and not force:
        print('No changes.')
        return

    if force:
        print('Forcing update')
    else:
        print('Diff:')
        print('\n'.join(d))
    want.send_to_ripe(password)
    print('Updated.')


def sync_autnum(members, password, force=False):
    print('Syncing aut-num...')
    want = IXPAutNum.make_for_members(members)
    got = IXPAutNum.from_ripe('AS208521')
    sync(want, got, password, force)



def sync_asset(members, password, force=False):
    print('Syncing as-set...')
    want = ASSet.make_for_members(members)
    got = ASSet.from_ripe('AS-CCCAMP19-IX')
    sync(want, got, password, force)



if __name__ == '__main__':
    if len(sys.argv) != 3:
        print("Usage: {} password AS1,AS2,AS3,...".format(sys.argv[0]))
        sys.exit(1)

    password = sys.argv[1]
    members = [m.strip().upper() for m in sys.argv[2].split(',')]

    for member in members:
        if not member.startswith('AS'):
            raise Exception('{} is not a valid ASN'.format(member))

        if not all(c in string.digits for c in member[2:]):
            raise Exception('{} is not a valid ASN'.format(member))

    sync_autnum(members, password)
    sync_asset(members, password)
