"""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

[((30, 21, 30, 57), 'flask.Blueprint', 'Blueprint', ({(30, 31, 30, 46): '"""invenio_madmp"""', (30, 48, 30, 56): '__name__'}, {}), "('invenio_madmp', __name__)", False, 'from flask import Blueprint, jsonify, request\n'), ((40, 15, 40, 27), 'flask.jsonify', 'jsonify', ({(40, 23, 40, 26): 'res'}, {}), '(res)', False, 'from flask import Blueprint, jsonify, request\n'), ((51, 19, 51, 46), 'flask.request.json.get', 'request.json.get', ({(51, 36, 51, 41): '"""dmp"""', (51, 43, 51, 45): '{}'}, {}), "('dmp', {})", False, 'from flask import Blueprint, jsonify, request\n'), ((58, 8, 58, 27), 'invenio_db.db.session.add', 'db.session.add', ({(58, 23, 58, 26): 'dmp'}, {}), '(dmp)', False, 'from invenio_db import db\n'), ((59, 8, 59, 27), 'invenio_db.db.session.commit', 'db.session.commit', ({}, {}), '()', False, 'from invenio_db import db\n'), ((75, 19, 75, 46), 'flask.request.json.get', 'request.json.get', ({(75, 36, 75, 41): '"""dmp"""', (75, 43, 75, 45): '{}'}, {}), "('dmp', {})", False, 'from flask import Blueprint, jsonify, request\n'), ((86, 8, 86, 27), 'invenio_db.db.session.commit', 'db.session.commit', ({}, {}), '()', False, 'from invenio_db import db\n'), ((68, 20, 68, 52), 'flask.request.args.get', 'request.args.get', ({(68, 37, 68, 43): '"""sync"""', (68, 45, 68, 51): '"""soft"""'}, {}), "('sync', 'soft')", False, 'from flask import Blueprint, jsonify, request\n'), ((47, 19, 47, 62), 'flask.jsonify', 'jsonify', ({(47, 27, 47, 61): "{'error': 'no json body supplied'}"}, {}), "({'error': 'no json body supplied'})", False, 'from flask import Blueprint, jsonify, request\n'), ((48, 13, 48, 36), 'flask.request.json.get', 'request.json.get', ({(48, 30, 48, 35): '"""dmp"""'}, {}), "('dmp')", False, 'from flask import Blueprint, jsonify, request\n'), ((55, 19, 55, 76), 'flask.jsonify', 'jsonify', ({(55, 27, 55, 75): "{'error': 'dmp with the same id already exists'}"}, {}), "({'error': 'dmp with the same id already exists'})", False, 'from flask import Blueprint, jsonify, request\n'), ((71, 19, 71, 62), 'flask.jsonify', 'jsonify', ({(71, 27, 71, 61): "{'error': 'no json body supplied'}"}, {}), "({'error': 'no json body supplied'})", False, 'from flask import Blueprint, jsonify, request\n'), ((72, 13, 72, 36), 'flask.request.json.get', 'request.json.get', ({(72, 30, 72, 35): '"""dmp"""'}, {}), "('dmp')", False, 'from flask import Blueprint, jsonify, request\n'), ((79, 19, 79, 82), 'flask.jsonify', 'jsonify', ({(79, 27, 79, 81): "{'error': 'mismatch between dmp id from url and body'}"}, {}), "({'error': 'mismatch between dmp id from url and body'})", False, 'from flask import Blueprint, jsonify, request\n'), ((83, 19, 83, 54), 'flask.jsonify', 'jsonify', ({(83, 27, 83, 53): "{'error': 'dmp not found'}"}, {}), "({'error': 'dmp not found'})", False, 'from flask import Blueprint, jsonify, request\n'), ((49, 19, 49, 66), 'flask.jsonify', 'jsonify', ({(49, 27, 49, 65): "{'error': 'dmp not found in the body'}"}, {}), "({'error': 'dmp not found in the body'})", False, 'from flask import Blueprint, jsonify, request\n'), ((73, 19, 73, 66), 'flask.jsonify', 'jsonify', ({(73, 27, 73, 65): "{'error': 'dmp not found in the body'}"}, {}), "({'error': 'dmp not found in the body'})", False, 'from flask import Blueprint, jsonify, request\n')]