from json import dumps

defaults = {
    'apt': {
        'repos': {
            'matrix': {
                'items': {
                    'deb https://packages.matrix.org/{os} {os_release} main',
                },
            },
        },
        'packages': {
            'matrix-synapse-py3': {},
        },
    },
    'backups': {
        'paths': {
            '/etc/matrix-synapse', # to backup the signing key
            '/var/lib/matrix-synapse',
        },
    },
    'icinga2_api': {
        'matrix-synapse': {
            'services': {
                'MATRIX-SYNAPSE PROCESS': {
                    'command_on_monitored_host': '/usr/lib/nagios/plugins/check_procs -a synapse.app.homeserver -c 1:',
                    'vars.notification.sms': True,
                },
            },
        },
    },
    'matrix-synapse': {
        'registration_shared_secret': repo.vault.human_password_for('{} matrix-synapse registration_shared_secret'.format(node.name)),
        'database': {
            'user': 'synapse_user',
            'password': repo.vault.password_for('{} postgresql synapse_user'.format(node.name)),
            'database': 'synapse',
        },
        'appservice_configs': set(),
    },
    'postgresql': {
        'roles': {
            'synapse_user': {
                'password': repo.vault.password_for('{} postgresql synapse_user'.format(node.name)),
            },
        },
        'databases': {
            'synapse': {
                'owner': 'synapse_user',
                'when_creating': {
                    'collation': 'C',
                    'ctype': 'C',
                },
            },
        },
    },
    'zfs': {
        'datasets': {
            'tank/matrix-synapse': {
                'mountpoint': '/var/lib/matrix-synapse',
                'needed_by': {
                    'pkg_apt:matrix-synapse-py3',
                },
            },
        },
    },
}

if node.has_bundle('telegraf'):
    defaults['telegraf'] = {
        'input_plugins': {
            'prometheus': {
                'matrix_synapse': {
                    'urls': [
                        'http://[::1]:20081/_synapse/metrics'
                    ],
                    'metric_version': 2,
                },
            },
        },
    }


@metadata_reactor.provides(
    'nginx/vhosts',
)
def nginx(metadata):
    if not node.has_bundle('nginx'):
        raise DoNotRunAgain

    wellknown_client_sliding_sync = {}
    if metadata.get('matrix-synapse/sliding_sync/version', None):
        wellknown_client_sliding_sync = {
            'org.matrix.msc3575.proxy': {
                'url': 'https://{}'.format(metadata.get('matrix-synapse/baseurl')),
            },
        }

    wellknown = {
        '/.well-known/matrix/client': {
            'content': dumps({
                'm.homeserver': {
                    'base_url': 'https://{}'.format(metadata.get('matrix-synapse/baseurl')),
                },
                'm.identity_server': {
                    'base_url': metadata.get('matrix-synapse/identity_server', 'https://matrix.org'),
                },
                **wellknown_client_sliding_sync,
                **metadata.get('matrix-synapse/additional_client_config', {}),
            }, sort_keys=True),
            'return': 200,
            'additional_config': {
                'default_type application/json',
                'add_header Access-Control-Allow-Origin *',
            },
        },
        '/.well-known/matrix/server': {
            'content': dumps({
                'm.server':  '{}:443'.format(metadata.get('matrix-synapse/baseurl')),
            }, sort_keys=True),
            'return': 200,
            'additional_config': {
                'default_type application/json',
                'add_header Access-Control-Allow-Origin *',
            },
        },
    }

    locations = {
        '/_client/': {
            'target': 'http://127.0.0.1:20070',
        },
        '/_matrix': {
            'target': 'http://[::1]:20080',
            'max_body_size': '50M',
        },
        '/_matrix/client/unstable/org.matrix.msc3575/sync': {
            'target': 'http://127.0.0.1:20070',
        },
        '/_synapse': {
            'target': 'http://[::1]:20080',
        },
        **wellknown,
    }

    if node.has_bundle('matrix-media-repo'):
        locations['/_matrix/media'] = {
            'target': 'http://localhost:20090',
            'max_body_size': '{}M'.format(metadata.get('matrix-media-repo/upload_max_mb')),
            # matrix-media-repo needs this to be the
            # homeserver address.
            'x_forwarded_host': metadata.get('matrix-synapse/server_name'),
        }

    vhosts = {
        'matrix-synapse': {
            'domain': metadata.get('matrix-synapse/baseurl'),
            'locations': locations,
            'website_check_path': '/_matrix/static/',
            'website_check_string': 'Synapse is running',
        },
    }

    for vname in metadata.get('matrix-synapse/wellknown_also_on_vhosts', set()):
        vhosts[vname] = {
            'locations': wellknown,
        }

    return {
        'nginx': {
            'vhosts': vhosts
        },
    }

@metadata_reactor.provides(
    'matrix-synapse/trusted_key_servers',
)
def autotrust_our_own_servers(metadata):
    domains = set()
    for rnode in repo.nodes:
        if not rnode.has_bundle('matrix-synapse'):
            continue

        domains.add(rnode.metadata.get('matrix-synapse/server_name'))

    return {
        'matrix-synapse': {
            'trusted_key_servers': domains,
        },
    }
