from formats.message_wrapper import message_wrapper_schema
from formats.mission_plan import mission_plan_schema
from formats.observation import observation_schema
from formats.planning_configuration import planning_configuration_schema
from formats.platform_status import platform_status_message_schema
from formats.acknowledgement import acknowledgement_schema

from flasgger import Swagger
from flask import Flask
# from openapi_schema_validator import validate
from openapi_spec_validator import validate_spec_url

app = Flask(__name__)

swagger_config = {
    "headers": [],
    "openapi": "3.1",
    "swagger_ui": True,
    "specs_route": "/",
    "info": {
        "title": "Backbone Message Formats",
        "version": "0.1",
        "description": "SoAR message schemas (i.e. formats)",
    },
    "specs": [
        {
            "endpoint": "swagger",
            "route": "/swagger.json",
            "rule_filter": lambda rule: True,
            "model_filter": lambda tag: True,
        }
    ],
    "definitions": {
        "Message": message_wrapper_schema,
        "MissionPlan": mission_plan_schema,
        "Observation": observation_schema,
        "PlanningConfiguration": planning_configuration_schema,
        "PlatformStatus": platform_status_message_schema,
        "Acknowledgement": acknowledgement_schema,
    },
    "paths": {
        "/all_messages": {
            "get": {
                "description": "Returns all messages from the system.",
                "responses": {
                    "200": {
                        "description": "A list of messages.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {"$ref": "#/definitions/Acknowledgement"},
                                        {"$ref": "#/definitions/PlatformStatus"},
                                        {"$ref": "#/definitions/MissionPlan"},
                                        {"$ref": "#/definitions/Observation"},
                                        {
                                            "$ref": "#/definitions/PlanningConfiguration"
                                        },
                                        {"$ref": "#/definitions/PlatformStatus"},
                                    ],
                                    "discriminator": {
                                        "propertyName": "message_type",
                                    },
                                }
                            }
                        },
                    }
                },
            }
        },
    },
    "produces": ["application/json"],
    "consumes": ["application/json"],
}
message_types = [
    "Message",
    "Acknowledgement",
    "MissionPlan",
    "Observation",
    "PlanningConfiguration",
    "PlatformStatus",
]
for item in message_types:
    swagger_config["paths"]["/" + str(item.lower())] = {
        "get": {
            "description": "Returns message for " + item,
            "responses": {
                "200": {
                    "description": item + " message.",
                    "content": {
                        "application/json": {
                            "schema": {
                                "allOf": [
                                    {
                                        "$ref": "#/definitions/" + item,
                                    },
                                ],
                                "discriminator": {
                                    "propertyName": "message_type",
                                },
                            }
                        }
                    },
                }
            },
        }
    }

swag = Swagger(app, config=swagger_config, merge=True)

# validate({"acknowledged_message_ID": "string-type-id", "status": "c2_received"}, acknowledgement_schema)


# app.add_url_rule(
#     '/coordinates',
#     view_func=Coordinates.as_view('coordinates'),
#     methods=['GET']
# )

from openapi_spec_validator import validate_spec, openapi_v3_spec_validator
if __name__ == "__main__":
    app.run(debug=True)
    # print(validate_spec_url("http://127.0.0.1:5000/swagger.json"))
    
    # If no exception is raised by validate_spec(), the spec is valid.
    # validate_spec(swagger_config)
    # print("000 Schema validation passed")

    # errors_iterator = openapi_v3_spec_validator.iter_errors(swagger_config)
    # print(errors_iterator)