import virtool.db.history
import virtool.db.refs
import virtool.db.utils
import virtool.kinds
import virtool.http.routes
import virtool.utils
from virtool.api.utils import compose_regex_query, json_response, not_found, paginate

routes = virtool.http.routes.Routes()


@routes.get("/api/refs")
async def find(req):
    db = req.app["db"]

    term = req.query.get("find", None)

    db_query = dict()

    if term:
        db_query.update(compose_regex_query(term, ["name", "data_type"]))

    data = await paginate(db.refs, db_query, req.query, sort="name", projection=virtool.refs.PROJECTION)

    return json_response(data)


@routes.get("/api/refs/{ref_id}")
async def get(req):
    """
    Get the complete representation of a specfic reference.

    """
    db = req.app["db"]

    document = await db.refs.find_one(req.match_info["ref_id"])

    if not document:
        return not_found()

    return json_response(document)


@routes.post("/api/refs", permission="create_ref", schema={
    "name": {
        "type": "string",
        "required": True
    },
    "description": {
        "type": "string",
        "default": ""
    },
    "data_type": {
        "type": "string",
        "allowed": ["genome", "barcode"],
        "default": "genome"
    },
    "organism": {
        "type": "string"
    },
    "public": {
        "type": "boolean",
        "default": False
    }

})
async def create(req):
    db = req.app["db"]
    data = req["data"]

    user_id = req["client"].user_id

    clone_from = data.get("clone_from", None)

    if clone_from:
        document = await virtool.db.refs.clone(
            db,
            data["name"],
            clone_from,
            data["description"],
            data["public"],
            user_id
        )

    else:
        document = await virtool.db.refs.create_document(
            db,
            data["name"],
            data["organism"],
            data["description"],
            data["data_type"],
            data["public"],
            user_id=req["client"].user_id
        )

    await db.refs.insert_one(document)

    headers = {
        "Location": "/api/refs/" + document["_id"]
    }

    return json_response(virtool.utils.base_processor(document), headers=headers, status=201)


@routes.get("/api/refs/{ref_id}/unbuilt")
async def get_unbuilt_changes(req):
    """
    Get a JSON document describing the unbuilt changes that could be used to create a new index.

    """
    db = req.app["db"]

    ref_id = req.match_info["ref_id"]

    history = await db.history.find({
        "ref.id": ref_id,
        "index.id": "unbuilt"
    }, virtool.db.history.LIST_PROJECTION).to_list(None)

    return json_response({
        "history": [virtool.utils.base_processor(c) for c in history]
    })

@@ -1,33 +1,96 @@
 import 
-virtool.db.history
+os%0A%0Aimport aiojobs.aiohttp%0A%0Aimport virtool.db.history%0Aimport virtool.db.processes
 %0Aimport 
@@ -133,29 +133,8 @@
 ils%0A
-import virtool.kinds%0A
 impo
@@ -156,16 +156,37 @@
 .routes%0A
+import virtool.kinds%0A
 import v
@@ -617,44 +617,8 @@
 ame%22
-, projection=virtool.refs.PROJECTION
 )%0A%0A 
@@ -1281,24 +1281,77 @@
 ome%22%0A    %7D,%0A
+    %22import_from%22: %7B%0A        %22type%22: %22string%22%0A    %7D,%0A
     %22organis
@@ -1614,24 +1614,72 @@
 from%22, None)
+%0A    import_from = data.get(%22import_from%22, None)
 %0A%0A    if clo
@@ -1874,32 +1874,32 @@
         user_id%0A
-
         )%0A%0A    e
@@ -1889,24 +1889,865 @@
 %0A        )%0A%0A
+    elif import_from:%0A        if not await db.files.count(%7B%22_id%22: import_from%7D):%0A            return not_found(%22File not found%22)%0A%0A        path = os.path.join(req.app%5B%22settings%22%5D%5B%22data_path%22%5D, %22files%22, import_from)%0A%0A        document = await virtool.db.refs.create_for_import(%0A            db,%0A            data%5B%22name%22%5D,%0A            data%5B%22description%22%5D,%0A            data%5B%22public%22%5D,%0A            import_from,%0A            user_id%0A        )%0A%0A        process = await virtool.db.processes.register(db, req.app%5B%22dispatch%22%5D, %22import_reference%22)%0A%0A        document%5B%22process%22%5D = %7B%0A            %22id%22: process%5B%22id%22%5D%0A        %7D%0A%0A        await aiojobs.aiohttp.spawn(req, virtool.db.refs.import_file(%0A            req.app,%0A            path,%0A            document%5B%22_id%22%5D,%0A            document%5B%22created_at%22%5D,%0A            process%5B%22id%22%5D,%0A            user_id%0A        ))%0A%0A
     else:%0A  

Extend ref api for importing