from auto_keyworder_modules import util
from hashlib import sha1
import hmac


def json_response(body, statuscode=200):
    return {
        'status_code': statuscode,
        'body': util.dumpjs(body),
        'headers': {
            'Content-Type': 'application/json; charset=utf-8',
        },
    }


def error_response(code, realm='user', msg=None):
    resp = {
        'realm': realm,
        'code': f'error.{realm}.{code}',
    }
    if msg is not None:
        resp['parameters'] = {'error': msg}
    return json_response(resp, 400)


def api_start_now(easydb_context, logger, parameters):
    try:
        signature = util.get_json_value(parameters, 'headers.X-Hub-Signature')
        if signature is None:
            util.log_error(logger, 'X-Hub-Signature missing')
            return error_response('not_authenticated')

        body = util.get_json_value(parameters, 'body')

        # check crypt algorithm
        crypt = 'sha1='
        if not signature.startswith(crypt):
            util.log_error(logger, 'X-Hub-Signature invalid')
            return error_response('not_authenticated')

        webhook_hmac = str(
            easydb_context.get_config('system.auto_keyworder.webhook_hmac')
        )
        if webhook_hmac is None:
            util.log_error(logger, 'system.auto_keyworder.webhook_hmac not defined')
            return error_response(
                'not_authenticated',
                'system.auto_keyworder.webhook_hmac not defined',
            )

        h = hmac.new(
            webhook_hmac.encode('utf-8'),
            body.encode('utf-8'),
            sha1,
        ).hexdigest()
        if crypt + h != signature:
            util.log_error(
                logger, f'X-Hub-Signature invalid: does not match {crypt}{h}'
            )
            return error_response('not_authenticated')

        util.log_info(
            logger, f'X-Hub-Signature {signature} ok: api request authenticated'
        )

        if set_start_now(easydb_context, True, logger):
            return json_response({'start_now_set': True})

        return json_response({'start_now_set': False})

    except Exception as e:
        util.log_error(logger, f'error during api call /start_now: {e}')
        util.print_traceback(logger, e)
        return error_response('internal_error', 'api', e)


def set_start_now(easydb_context, value: bool, logger) -> bool:
    try:
        conn = easydb_context.db_connect('easydb-auto-keyworder-plugin')
        cursor = conn.cursor()

        # get ez_value:id
        cursor.execute(
            f"""
                SELECT "ez_value:id"
                FROM    ez_base_config
                WHERE   class     = 'system'
                AND     key       = 'auto_keyworder'
                AND     parameter = 'start_now'
            """
        )

        res = cursor.fetchall()
        if len(res) != 1:
            return False
        ez_value_id = int(res[0]['ez_value:id'])

        # set value for ez_value:id
        cursor.execute(
            f"""
                UPDATE ez_value
                SET    value_bool   = {("true" if value else "false")}
                WHERE "ez_value:id" = {ez_value_id}
            """
        )

        conn.commit()

        conn.close()

        util.log_info(
            logger, f'set baseconfig entry system.auto_keyworder.start_now to {value}'
        )
        return True

    except Exception as e:
        conn.close()
        util.print_traceback(logger, e)

    return False
