"""Blueprint definitions for maDMP integration."""

from flask import Blueprint, jsonify, request
from invenio_db import db

from .convert import convert_dmp
from .models import DataManagementPlan


def _summarize_dmp(dmp: DataManagementPlan) -> dict:
    """Create a summary dictionary for the given DMP."""
    res = {"dmp_id": dmp.dmp_id, "datasets": []}

    for ds in dmp.datasets:
        dataset = {"dataset_id": ds.dataset_id, "record": None}

        if ds.record:
            dataset["record"] = ds.record.model.json

        res["datasets"].append(dataset)

    return res


def create_rest_blueprint(app) -> Blueprint:
    """Create the blueprint for the REST endpoints using the current app extensions."""
    # note: using flask.current_app isn't directly possible, because Invenio-MaDMP is
    #       registered as an extension in the API app, not the "normal" app
    #       (which is the one usually returned by current_app)
    rest_blueprint = Blueprint("invenio_madmp", __name__)
    auth = app.extensions["invenio-madmp"].auth

    @rest_blueprint.route("/dmps", methods=["GET"])
    @auth.login_required
    def list_dmps():
        """Give a summary of all stored DMPs."""
        dmps = DataManagementPlan.query.all()
        res = [_summarize_dmp(dmp) for dmp in dmps]

        return jsonify(res)

    @rest_blueprint.route("/dmps", methods=["POST"])
    @auth.login_required
    def create_dmp():
        """Create a new DMP from the maDMP JSON in the request body."""
        if request.json is None:
            return jsonify({"error": "no json body supplied"}), 400
        elif request.json.get("dmp") is None:
            return jsonify({"error": "dmp not found in the body"}), 400

        dmp_json = request.json.get("dmp", {})
        dmp_json_id = dmp_json.get("dmp_id", {}).get("identifier")

        if DataManagementPlan.get_by_dmp_id(dmp_json_id) is not None:
            return jsonify({"error": "dmp with the same id already exists"}), 409

        dmp = convert_dmp(dmp_json)
        db.session.add(dmp)
        db.session.commit()

        # TODO change the returned value
        return jsonify(_summarize_dmp(dmp)), 201

    @rest_blueprint.route("/dmps/<dmp_id>", methods=["PATCH"])
    @auth.login_required
    def update_dmp(dmp_id: str = None):
        """Update the specified DMP using the maDMP JSON in the request body."""
        hard_sync = request.args.get("sync", "soft") == "hard"

        if request.json is None:
            return jsonify({"error": "no json body supplied"}), 400
        elif request.json.get("dmp") is None:
            return jsonify({"error": "dmp not found in the body"}), 400

        dmp_json = request.json.get("dmp", {})
        dmp_json_id = dmp_json.get("dmp_id", {}).get("identifier")

        if dmp_id and dmp_json_id and dmp_id != dmp_json_id:
            return jsonify({"error": "mismatch between dmp id from url and body"}), 400

        dmp_id = dmp_id or dmp_json_id
        if DataManagementPlan.get_by_dmp_id(dmp_id) is None:
            return jsonify({"error": "dmp not found"}), 404

        dmp = convert_dmp(dmp_json, hard_sync)
        db.session.commit()

        # TODO change the returned value
        return jsonify(_summarize_dmp(dmp))

    @rest_blueprint.route("/dmps", methods=["PATCH"])
    @auth.login_required
    def update_dmp_without_id():
        """Update the specified DMP using the maDMP JSON in the request body."""
        return update_dmp(None)

    return rest_blueprint

[((965, 1001), 'flask.Blueprint', 'Blueprint', (['"""invenio_madmp"""', '__name__'], {}), "('invenio_madmp', __name__)\n", (974, 1001), False, 'from flask import Blueprint, jsonify, request\n'), ((1312, 1324), 'flask.jsonify', 'jsonify', (['res'], {}), '(res)\n', (1319, 1324), False, 'from flask import Blueprint, jsonify, request\n'), ((1737, 1764), 'flask.request.json.get', 'request.json.get', (['"""dmp"""', '{}'], {}), "('dmp', {})\n", (1753, 1764), False, 'from flask import Blueprint, jsonify, request\n'), ((2030, 2049), 'invenio_db.db.session.add', 'db.session.add', (['dmp'], {}), '(dmp)\n', (2044, 2049), False, 'from invenio_db import db\n'), ((2058, 2077), 'invenio_db.db.session.commit', 'db.session.commit', ([], {}), '()\n', (2075, 2077), False, 'from invenio_db import db\n'), ((2682, 2709), 'flask.request.json.get', 'request.json.get', (['"""dmp"""', '{}'], {}), "('dmp', {})\n", (2698, 2709), False, 'from flask import Blueprint, jsonify, request\n'), ((3144, 3163), 'invenio_db.db.session.commit', 'db.session.commit', ([], {}), '()\n', (3161, 3163), False, 'from invenio_db import db\n'), ((2399, 2431), 'flask.request.args.get', 'request.args.get', (['"""sync"""', '"""soft"""'], {}), "('sync', 'soft')\n", (2415, 2431), False, 'from flask import Blueprint, jsonify, request\n'), ((1550, 1593), 'flask.jsonify', 'jsonify', (["{'error': 'no json body supplied'}"], {}), "({'error': 'no json body supplied'})\n", (1557, 1593), False, 'from flask import Blueprint, jsonify, request\n'), ((1612, 1635), 'flask.request.json.get', 'request.json.get', (['"""dmp"""'], {}), "('dmp')\n", (1628, 1635), False, 'from flask import Blueprint, jsonify, request\n'), ((1922, 1979), 'flask.jsonify', 'jsonify', (["{'error': 'dmp with the same id already exists'}"], {}), "({'error': 'dmp with the same id already exists'})\n", (1929, 1979), False, 'from flask import Blueprint, jsonify, request\n'), ((2495, 2538), 'flask.jsonify', 'jsonify', (["{'error': 'no json body supplied'}"], {}), "({'error': 'no json body supplied'})\n", (2502, 2538), False, 'from flask import Blueprint, jsonify, request\n'), ((2557, 2580), 'flask.request.json.get', 'request.json.get', (['"""dmp"""'], {}), "('dmp')\n", (2573, 2580), False, 'from flask import Blueprint, jsonify, request\n'), ((2858, 2921), 'flask.jsonify', 'jsonify', (["{'error': 'mismatch between dmp id from url and body'}"], {}), "({'error': 'mismatch between dmp id from url and body'})\n", (2865, 2921), False, 'from flask import Blueprint, jsonify, request\n'), ((3047, 3082), 'flask.jsonify', 'jsonify', (["{'error': 'dmp not found'}"], {}), "({'error': 'dmp not found'})\n", (3054, 3082), False, 'from flask import Blueprint, jsonify, request\n'), ((1664, 1711), 'flask.jsonify', 'jsonify', (["{'error': 'dmp not found in the body'}"], {}), "({'error': 'dmp not found in the body'})\n", (1671, 1711), False, 'from flask import Blueprint, jsonify, request\n'), ((2609, 2656), 'flask.jsonify', 'jsonify', (["{'error': 'dmp not found in the body'}"], {}), "({'error': 'dmp not found in the body'})\n", (2616, 2656), False, 'from flask import Blueprint, jsonify, request\n')]