import motor.motor_asyncio
import mongomock
import asyncio
from unittest.mock import MagicMock

class MockAsyncIOMotorClient:
    def __init__(self, *args, **kwargs):
        self.mock_client = mongomock.MongoClient()
        print("Using mongomock fallback!")

    def __getitem__(self, name):
        return MockAsyncIOMotorDatabase(self.mock_client[name])

    def close(self):
        pass

class MockAsyncIOMotorDatabase:
    def __init__(self, db):
        self.db = db
        self.users = MockAsyncIOMotorCollection(db.users)
        self.game_scores = MockAsyncIOMotorCollection(db.game_scores)
        self.enrollments = MockAsyncIOMotorCollection(db.enrollments)

    def __getitem__(self, name):
        return MockAsyncIOMotorCollection(self.db[name])

class MockAsyncIOMotorCollection:
    def __init__(self, collection):
        self.collection = collection

    async def find_one(self, *args, **kwargs):
        return self.collection.find_one(*args, **kwargs)

    async def insert_one(self, *args, **kwargs):
        return self.collection.insert_one(*args, **kwargs)

    async def update_one(self, *args, **kwargs):
        return self.collection.update_one(*args, **kwargs)

    def find(self, *args, **kwargs):
        cursor = self.collection.find(*args, **kwargs)
        return MockCursor(cursor)

    def aggregate(self, pipeline):
        cursor = self.collection.aggregate(pipeline)
        return MockCursor(cursor)

class MockCursor:
    def __init__(self, cursor):
        self.cursor = cursor

    def sort(self, *args, **kwargs):
        self.cursor.sort(*args, **kwargs)
        return self

    def limit(self, *args, **kwargs):
        self.cursor.limit(*args, **kwargs)
        return self

    async def to_list(self, length):
        return list(self.cursor)

# Monkeypatch
motor.motor_asyncio.AsyncIOMotorClient = MockAsyncIOMotorClient

import server
import uvicorn

if __name__ == "__main__":
    uvicorn.run(server.app, host="0.0.0.0", port=8001)
