import json
import os
import sys
import pytest

# sources/ doit être dans le path pour les imports
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))


@pytest.fixture(scope="session")
def app():
    from flask import Flask
    from db import db as _db

    flask_app = Flask(
        __name__,
        template_folder=os.path.join(os.path.dirname(os.path.dirname(__file__)), "templates"),
    )
    flask_app.config.update({
        "TESTING": True,
        "SQLALCHEMY_DATABASE_URI": "sqlite:///:memory:",
        "SQLALCHEMY_TRACK_MODIFICATIONS": False,
        "SECRET_KEY": "test-secret",
        "INSTANCE_NAME": "test",
        "YUNOHOST_BACKUP_DIR": "/tmp/bm_test_backups",
        "DATA_DIR": "/tmp/bm_test_data",
        "API_TOKEN": "test-token",
        "INSTANCE_URL": "http://localhost",
        "LOG_PATH": "/tmp/bm_test.log",
    })
    flask_app.jinja_env.filters["fromjson"] = json.loads
    _db.init_app(flask_app)

    from blueprints.settings import bp as bp_cfg
    from blueprints.jobs import bp as bp_jobs
    from blueprints.destinations import bp as bp_dest
    from blueprints.network import bp as bp_net
    from blueprints.api import bp as bp_api
    flask_app.register_blueprint(bp_cfg)
    flask_app.register_blueprint(bp_jobs)
    flask_app.register_blueprint(bp_dest)
    flask_app.register_blueprint(bp_net)
    flask_app.register_blueprint(bp_api)

    @flask_app.context_processor
    def _inject():
        from datetime import datetime as _dt
        return {
            "instance_name": flask_app.config.get("INSTANCE_NAME", ""),
            "instance_url": flask_app.config.get("INSTANCE_URL", ""),
            "api_token": flask_app.config.get("API_TOKEN", ""),
            "now": _dt.utcnow(),
        }

    with flask_app.app_context():
        _db.create_all()

    return flask_app


@pytest.fixture
def client(app):
    return app.test_client()


@pytest.fixture(autouse=True)
def clean_db(app):
    with app.app_context():
        yield
        from db import db as _db
        _db.session.remove()
        for table in reversed(_db.metadata.sorted_tables):
            _db.session.execute(table.delete())
        _db.session.commit()
