from flask import Flask
from flask_cors import CORS

from graph.exploration.llm.logging_dataset import logging_dataset


def run_create_app(app: Flask, testing_context: bool = False):
    from backends.logging_setup import logging_setup

    logging_setup()

    from backends.editor.utils.store import (
        get_or_create_graph_diskcache_dir,
        get_or_create_kuzu_db_instance_access_diskcache_dir,
        get_or_create_snapshot_diskcache_dir,
    )

    # Create and fill env variables for diskcache locations.
    # If it is not done, each child processes will have its own diskcache location which defeats the whole idea.
    get_or_create_graph_diskcache_dir()
    get_or_create_snapshot_diskcache_dir()
    get_or_create_kuzu_db_instance_access_diskcache_dir()

    if not testing_context:
        from .webapp_config import webapp_config

        webapp_config.setup()

        if webapp_config.logging_ds:
            logging_dataset.init(webapp_config.logging_ds)

    from backends.editor.api import api

    CORS(app)

    app.register_blueprint(api)

    from pydantic import ValidationError

    from backends.middlewares import (
        handle_concurrent_update_error,
        handle_feature_unavailable_error,
        handle_graph_already_exists_error,
        handle_graph_db_being_built_error,
        handle_graph_db_not_exist_error,
        handle_graph_does_not_exist_error,
        handle_model_validation_error,
        handle_preset_not_set_error,
        handle_snapshot_does_not_exist_error,
        handle_unexpected_error,
        handle_validation_error,
    )
    from solutions.graph.models import (  # noqa: F401
        FeatureUnavailableError,
        GraphAlreadyExistsError,
        GraphDBDoesNotExistError,
        GraphDBWriteInProgressError,
        GraphDoesNotExistError,
        ModelValidationError,
        PresetNotSetException,
        SnapshotDoesNotExistError,
    )
    from stores.graph_metadata_store import ConcurrentUpdateCollisionError

    app.register_error_handler(ValidationError, handle_validation_error)  # type: ignore
    app.register_error_handler(GraphDoesNotExistError, handle_graph_does_not_exist_error)  # type: ignore
    app.register_error_handler(GraphAlreadyExistsError, handle_graph_already_exists_error)  # type: ignore
    app.register_error_handler(GraphDBWriteInProgressError, handle_graph_db_being_built_error)  # type: ignore
    app.register_error_handler(GraphDBDoesNotExistError, handle_graph_db_not_exist_error)  # type: ignore
    app.register_error_handler(ConcurrentUpdateCollisionError, handle_concurrent_update_error)  # type: ignore
    app.register_error_handler(SnapshotDoesNotExistError, handle_snapshot_does_not_exist_error)  # type: ignore
    app.register_error_handler(FeatureUnavailableError, handle_feature_unavailable_error)  # type: ignore
    app.register_error_handler(ModelValidationError, handle_model_validation_error)  # type: ignore
    app.register_error_handler(PresetNotSetException, handle_preset_not_set_error)  # type: ignore
    app.register_error_handler(Exception, handle_unexpected_error)  # type: ignore

    return app
