import traceback
import json
from urllib.parse import urljoin

import wordpress_util
import oauth2
import fylr_lib_plugin_python3.util as fylr_util


def easydb_server_start(easydb_context):
    logger = easydb_context.get_logger('transport.wordpress')
    logger.debug('initialize Wordpress plugin')

    easydb_context.register_callback(
        'export_transport',
        {
            'transport_type': 'wordpress',
            'callback': 'transport_wp',
        },
    )

    easydb_context.register_callback(
        'api',
        {
            'name': 'oauth2',
            'callback': 'api_oauth2',
        },
    )


def api_oauth2(easydb_context, parameters):
    logger = easydb_context.get_logger('transport.wordpress')
    try:
        config = easydb_context.get_config()
        plugin = easydb_context.get_plugin('easydb-wordpress-plugin')

        response = oauth2.authenticate(
            query_params=parameters.get('query_string_parameters', {}),
            plugin_url=urljoin(
                urljoin(
                    config.get('system').get('server').get('external_url'),
                    plugin.get('plugin_url'),
                ),
                'oauth2',
            ),
            config_js=config.get('base', {}).get('system', {}),
        )

        logger.debug(f'oauth2 response: {response}')
        return response

    except Exception as e:
        logger.error('\n'.join(fylr_util.get_exception_traceback(e)))
        raise e


def transport_wp(easydb_context, protocol=None):
    logger = easydb_context.get_logger('transport.wordpress')
    logger.debug('Transport Wordpress Start.')

    try:

        exp = easydb_context.get_exporter()
        transport_def = exp.getCurrentTransport()

        if not transport_def:
            raise Exception('failed to get current transport')

        transport_opts = transport_def.get('options', {})
        wp_inst_uuid = transport_opts.get('wp_inst_uuid', '')

        config = easydb_context.get_config()

        wp_inst, auth = wordpress_util.get_wp_instance_and_auth_by_uuid(
            config.get('base', {}).get('system', {}),
            wp_inst_uuid,
        )

        logger.debug('=== WP INST:')
        logger.debug(fylr_util.dumpjs(wp_inst))
        logger.debug('=== WP INST AUTH:')
        logger.debug(fylr_util.dumpjs(auth))

        wp_inst_url = wp_inst.get('url', '')
        wp_api_url = wordpress_util.discover_wp_api_url(wp_inst_url)

        logger.debug(f'=== WP URL: {wp_api_url}')
        wp_media_url = f'{wp_api_url}/media'
        logger.debug(f'=== WP Media URL: {wp_media_url}')

        events, _protocol, _state = wordpress_util.transport_files(
            wp_media_url=wp_media_url,
            fpath=exp.getFilesPath(),
            files=exp.getFiles(),
            auth=auth,
            user_generated_displayname=transport_opts.get('user_generated_displayname'),
            source_name='easydb',
        )
        if protocol:
            _protocol = [f'Wordpress: {wp_inst_url}'] + _protocol
            for _p in _protocol:
                protocol.add_notice(_p)

        # log events in export
        event_name = wordpress_util.get_event_name(exp.isScheduled())
        for e in events:
            if not 'name' in e:
                e['name'] = event_name
            exp.logEvent(e)

        if _state == 'failed':
            raise Exception('transport to wordpress failed')

    except Exception as e:
        logger.error('\n'.join(fylr_util.get_exception_traceback(e)))
        raise e
