import logging
import os
import warnings

import pydantic.warnings
from flask import Flask

from backend.cache import cache
from backend.config import get_workload_folder_path
from backend.database.store import SQLiteStore
from backend.fetch_api import fetch_api
from backend.routes import api
from backend.socket import socketio
from backend.utils.logging_utils import configure_logging
from backend.utils.ws_utils import before_request as auth_before_request
from backend.utils.ws_utils import setup_socketio

os.environ["LANGCHAIN_TRACING_V2"] = "false"

import langsmith

# logging.basicConfig(level=logging.DEBUG)


def my_warning_handler(message, category, filename, lineno, file=None, line=None):
    if issubclass(category, pydantic.warnings.PydanticDeprecatedSince20):
        return  # ignore this warning
    if issubclass(category, langsmith.utils.LangSmithMissingAPIKeyWarning):
        return  # ignore this warning
    import sys

    sys.stderr.write(warnings.formatwarning(message, category, filename, lineno, line))


warnings.showwarning = my_warning_handler


class NoParsingFilter(logging.Filter):
    def filter(self, record):
        message = record.getMessage()
        return not message.endswith("AssertionError: write() before start_response")


def setup_app(app: Flask):
    cache.init_app(app)
    app.register_blueprint(blueprint=fetch_api)
    app.register_blueprint(blueprint=api)
    app.before_request(auth_before_request)
    db_folder_path = get_workload_folder_path()
    if not (db_folder_path):
        raise ValueError("DB Folder Path is required to store SQLite.")
    print(f"DB folder path: {db_folder_path}")  # TODO maybe remove later?
    db_filename = "data_store.db"
    store = SQLiteStore(os.path.join(db_folder_path, db_filename))

    # store.start_connection_monitor(interval_seconds=10)
    app.config["STORE"] = store

    @app.teardown_appcontext
    def close_store_connection(exception=None):
        store.close_thread_connection()

    configure_logging()
    logging.getLogger("werkzeug").addFilter(NoParsingFilter())
    socketio.init_app(app)
    setup_socketio(socketio)
    from backend.indexing_monitor import start_monitor, wake_monitor

    start_monitor(app, interval=5)
    wake_monitor()

    from backend.services.publishing_service import PublishingService

    publishing_service = PublishingService(app.config["STORE"])
    app.config["PUBLISHING_SERVICE"] = publishing_service
    publishing_service.resume_publishing_jobs()
