import traceback
import json
from urllib.parse import urljoin

import wordpress_util
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',
        },
    )

    # TODO: OAuth1 is deprecated and does not work with newer servers! Remove or replace!
    # easydb_context.register_callback(
    #     'api',
    #     {
    #         'name': 'oauth1',
    #         'callback': 'api_oauth1',
    #     },
    # )


def api_oauth1(easydb_context, parameters):
    try:
        return _api_oauth1(easydb_context, parameters)
    except Exception as e:
        traceback.print_exc()
        raise


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

    response = wordpress_util.oauth1(
        query_params=parameters.get('query_string_parameters', {}),
        plugin_url=urljoin(
            config.get('system').get('server').get('external_url'),
            plugin.get('plugin_url'),
        ),
        logger=logger,
    )

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


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

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

    if not transport:
        wordpress_util.raise_error('failed to get current transport')

    opts = transport.get('options', {})
    wp_inst_uuid = opts.get('wp_inst_uuid')

    config = easydb_context.get_config()

    wp_conf = config.get('base', {}).get('system', {}).get('wordpress', {})
    if not wp_conf:
        wordpress_util.raise_error('wordpress config not found')

    wp_inst = {}
    auth = {}
    for _wp_inst in wp_conf.get('wp_instances', []):
        auth = json.loads(_wp_inst['auth'])
        if auth.get('uuid', '') == wp_inst_uuid:
            wp_inst = _wp_inst
            break

    if not wp_inst:
        wordpress_util.raise_error('wordpress instance not found')

    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.build_wp_api_url(wp_inst_url)
    if not wp_api_url:
        wordpress_util.raise_error('api discovery failed')

    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=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':
        wordpress_util.raise_error('transport to wordpress failed')
