from __future__ import annotations

import logging

from flask import Blueprint, request

from backends.explorer.connections.db_handler_registry import get_handler_for_snapshot
from backends.explorer.queries.explorer_data import (
    run_cypher_query,
)
from backends.explorer.queries.params import ExplorerRunCypherParams
from backends.explorer.utils.webapp_config import webapp_config
from backends.utils import return_ok
from graph.exploration.cypher_graph_view import CypherQueryExecutionException
from solutions.graph.models import PresetNotSetException

logger = logging.getLogger(__name__)

graph_cypher = Blueprint("data", __name__, url_prefix="/cypher")


@graph_cypher.route("/run", methods=["POST"])
def run_cypher():
    params = ExplorerRunCypherParams(**request.get_json())
    try:
        db_folders = webapp_config.db_explorer_folders
        db_handler = get_handler_for_snapshot(params.snapshot_id, db_folders)
        result = run_cypher_query(
            params,
            db_folders,
            db_handler,
            timeout_seconds=webapp_config.db_query_timeout_seconds,
        )
        return return_ok(data=result)
    except PresetNotSetException as ex:
        raise ex
    except CypherQueryExecutionException as ex:
        logger.info(
            f"User query raised an error on saved configuration {params.snapshot_id}, '{params.query}'.", exc_info=True
        )
        return return_ok(data=str(ex))
    except Exception as ex:
        logger.exception(
            f"An unexpected error occured on saved configuration {params.snapshot_id}, '{params.query}'.", exc_info=True
        )
        return return_ok(data=str("An unexpected error occured."))
