message_header = {
    "type": "object",
    "discriminator": {
        "propertyName": "message_type",
    },
    "properties": {
        "message_ID": {
            "type": "string",
            "description": "An identifier for the type of message received.",
            "example": "b427003c-0000-11aa-a1eb-b1cdf2342fdd",
        },
        "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of message",
            "example": "2022-11-16T00:00:00Z",
        },
        "version": {
            "type": "number",
            "format": "float",
            "description": "Version of comms backbone message format protocol",
            "example": 2.0,
        },
        "source": {
            "type": "string",
            "description": "The sender; Where is this message from",
            "example": "autonomy_engine",
        },
        "destination": {
            "type": "string",
            "description": "Publisher topic; What is the destination"
            + " of this message",
            "example": "ah1",
        },
        "encoded": {
            "type": "boolean",
            "description": "Indicate that message raw (encoded) or decoded. "
            + "Options: encoded=true, decoded=false",
            "example": False,
        },
        "delivery_type": {
            "type": "string",
            "description": "To publish or broadcast this message.",
            "enum": ["broadcast", "publish"],
            "example": "publish",
            "default": "publish",
        },
    },
}

acknowledgement_schema = {
    "type": "object",
    "properties": {
        "message_type": {
            "type": "string",
            "description": "Type of message",
            "example": "acknowledgement",
        },
        "autonomy_engine_plan_ID": {
            "type": "integer",
            "description": "Mission plan ID (according to Autonomy"
            + " Engine's mission plan number sent) executed by platform",
            "example": 1,
        },
        "platform_ID": {
            "type": "string",
            "description": "Unique identifier for this platform",
            "example": "reav-x-1",
        },
        "approved": {
            "type": "boolean",
            "description": "Human-in-the-loop approval. "
            + "1 - Plan approved; 0 - Plan Rejected",
        },
    },
    "required": [
        "message_type",
        "autonomy_engine_plan_ID",
        "platform_ID",
        "approved",
    ],
}


action_schema = {
    "type": "object",
    "properties": {
        "action": {
            "type": "string",
            "description": "Autonomy Engine's action from `move`, `payload`,"
            + " `dive`, `send_hits`, `scanline`, `scanpoint`.",
            "example": "move",
        },
        "start_point_latitude": {
            "type": "number",
            "format": "float",
            "description": "Start point, x-coordinate",
            "example": -4.187143188645706,
        },
        "start_point_longitude": {
            "type": "number",
            "format": "float",
            "description": "Start point, y-coordinate",
            "example": 50.37072283932642,
        },
        "target_waypoint_latitude": {
            "type": "number",
            "format": "float",
            "description": "Target waypoint, x-coordinate",
            "example": -4.187143188645706,
        },
        "target_waypoint_longitude": {
            "type": "number",
            "format": "float",
            "description": "Target waypoint, y-coordinate",
            "example": 50.37072283932642,
        },
        "altitude": {
            "type": "number",
            "format": "float",
            "description": "Altitude of next action",
            "example": 15.0,
        },
        "depth": {
            "type": "number",
            "format": "float",
            "description": "Depth of next action",
            "example": 15.0,
        },
        "activate_payload": {
            "type": "boolean",
            "description": "To activate/deactivate sensor for Autosub "
            + "Hover-1 --> `MBES` sensor and for EcoSUB --> `Sidescan`",
            "example": True,
        },
        "timeout": {
            "type": "number",
            "format": "float",
            "description": "Timeout set to perform action",
            "example": 1800.0,
        },
    },
    "required": [
        "target_waypoint_latitude",
        "target_waypoint_longitude",
    ],
}

mission_plan_schema = {
    "type": "object",
    "properties": {
        "message_type": {
            "type": "string",
            "description": "Type of message",
            "example": "mission_plan",
        },
        "autonomy_engine_plan_ID": {
            "type": "integer",
            "description": "Unique identifier for this plan"
            + "generated by the Autonomy Engine",
            "example": 3,
        },
        "platform_ID": {
            "type": "string",
            "description": "Unique identifier for this platform",
            "example": "reav-x-1",
        },
        "emergency": {
            "default": False,
            "description": "To indicate if this is an emergency. "
            + "true = emergency and false = no emergency",
            "example": False,
            "type": "boolean",
        },
        "plan": {
            "type": "array",
            "items": action_schema,
        },
    },
    "required": [
        "message_type",
        "autonomy_engine_plan_ID",
        "platform_ID",
        "plan",
    ],
}


hits_schema = {
    "type": "object",
    "properties": {
        "latitude": {
            "type": "number",
            "format": "float",
            "description": "Identified x-coordinate of point of interest",
            "example": 178.2,
        },
        "longitude": {
            "type": "number",
            "format": "float",
            "description": "Identified y-coordinate of point of interest",
            "example": -10.122,
        },
        "quality_of_point": {
            "type": "number",
            "format": "float",
            "description": "Quality/strength of points from features of"
            + " interest identified by platform.",  # TODO: DEFINE FORMAT.
            "example": 0.98,
        },
    },
    "required": ["latitude", "longitude"],
}

observation_schema = {
    "type": "object",
    "properties": {
        "message_type": {
            "type": "string",
            "description": "Type of message",
            "example": "observation",
        },
        "platform_ID": {
            "type": "string",
            "description": "Unique identifier for this platform",
            "example": "reav-x-1",
        },
        "points_of_interest": {
            "type": "array",
            "items": hits_schema,
            "description": "Points from features of interest identified by"
            + " platform if any found.",  # TODO: DEFINE FORMAT.
        },
        "region_surveyed": {
            "nullable": True,
            "description": "Region surveyed by given platform."
            + " GEOJSON",  # TODO: DEFINE FORMAT.
            "example": "",
        },
        "additional_data": {
            "description": "Placeholder field for any additional data",
            "example": {"sensor_payload": False},
        },
    },
    "required": ["message_type", "platform_ID"],
}

emergency_schema = {
    "type": "object",
    "properties": {
        "safe_command": {
            "type": "string",
            "enum": ["go_home", "abort_now", "stop_now", "surface_now"],
            "description": "Command/Action that is native to respective"
            + " partner's platform/C2",
            "example": "go_home",
        },
        "target_waypoint_latitude": {
            "type": "number",
            "format": "float",
            "description": "X-coordinate safe place for respective platform",
            "example": 50.365,
        },
        "target_waypoint_longitude": {
            "type": "number",
            "format": "float",
            "description": "Y-coordinate safe place for respective platform",
            "example": -7.432,
        },
        "target_depth": {
            "type": "number",
            "format": "float",
            "description": "Z-coordinate safe place for respective platform"
            + " . If platform to NOT stay at depth, key in `0.0`",
            "example": 10.0,
        },
        "additional_data": {
            "description": "Any addition fields/data to be added here",
            "example": {},
        },
    },
    "required": [
        "target_waypoint_latitude",
        "target_waypoint_longitude",
        "target_depth",
    ],
}


platform_schema = {
    "type": "object",
    "properties": {
        "platform_ID": {
            "type": "string",
            "description": "Unique identifier for this platform",
            "example": "reav-x-1",
        },
        "model": {
            "type": "string",
            "example": "reav",
        },
        "emergency": emergency_schema,
        "min_altitude": {
            "type": "number",
            "format": "float",
            "description": "Minimum altitude set for squad.",
            "example": 15.2,
        },
        "min_velocity": {
            "type": "number",
            "format": "float",
            "description": "Minimum velocity set for squad.",
            "example": 0.1,
        },
        "max_velocity": {
            "type": "number",
            "format": "float",
            "description": "Maximum velocity set for squad.",
            "example": 0.9,
        },
        "additional_data": {
            "description": "Any addition fields/data to be added here",
            "example": {"swath_width": 10.0, "scan_type": "DVL"},
        },
    },
    "required": [
        "platform_ID",
        "model",
        "emergency",
        "min_altitude",
        "min_velocity",
        "max_velocity",
    ],
}

region_schema = {
    "type": "object",
    "properties": {
        "geometry_coordinates": {
            "type": "array",  # TODO: Check if config defn is right.
            "example": [
                [
                    [-4.187143188645706, 50.37072283932642],
                    [-4.202697005964865, 50.368816892405874],
                    [-4.203156724702808, 50.365640144076906],
                    [-4.19449868846155, 50.362267670845654],
                ]
            ],
        },
    },
    "description": "Using GEOJSON, exact 4-point region (rectangle shaped)",
}

squad_metadata_schema = {
    "type": "object",
    "properties": {
        "squad_ID": {
            "type": "integer",
            "description": "Identifier of given squad",
            "example": 23,
        },
        "no_of_platforms": {
            "type": "integer",
            "description": "Number of platforms",
            "example": 3,
        },
        "platforms": {
            "type": "array",
            "items": platform_schema,
            "description": "Squad consists of these platforms",
        },
        "squad_mission_type": {
            "type": "string",
            "enum": ["tracking", "survey", "inspection"],
            "description": "Mission of given squad: `tracking`, `survey`"
            + ", `inspection`",
            "example": "survey",
        },
        "squad_state": {
            "type": "string",
            "description": "In execution, Waiting.. <define further>",
            "example": False,
        },
        "region_of_interest": region_schema,
    },
    "required": [
        "squad_ID",
        "no_of_platforms",
        "platforms",
        "squad_mission_type",
        "squad_state",
    ],
}

planning_configuration_schema = {
    "type": "object",
    "properties": {
        "message_type": {
            "type": "string",
            "description": "Type of message",
            "example": "planning_configuration",
        },
        "planning_config_ID": {
            "type": "integer",
            "description": "Unique identifier tagged to version of this"
            + " configuration plan",
            "example": 3,
        },
        "exclusion_zones": {
            "type": "array",
            "items": region_schema,
            "description": "Exclusion zones for all platforms",
        },
        "squads": {
            "type": "array",
            "items": squad_metadata_schema,
        },
    },
    "required": [
        "message_type",
        "planning_config_ID",
        "squads",
        "exclusion_zones",
    ],
}


sensor_schema = {
    "type": "object",
    "description": "Scanning sensor on platform available"
    + " to be controlled by  the Autonomy Engine",
    "properties": {
        "sensor_serial": {
            "type": "string",
            "description": "serial number of sensor",
            "example": "mbes-002a",
        },
        "sensor_on": {
            "type": "boolean",
            "description": "Sensor switched on (true) or off (false)",
            "example": True,
        },
        "additional_data": {
            "description": "Any addition fields/data to be added here",
            "example": {"payload": [1.2, 434]},
        },
    },
}

platform_status_schema = {
    "type": "object",
    "properties": {
        "message_type": {
            "type": "string",
            "description": "Type of message",
            "example": "platform_status",
            "enum": ["platform_status"],
        },
        "platform_ID": {
            "type": "string",
            "description": "Unique identifier for this platform",
            "example": "reav-x-1",
        },
        "status_source": {
            "type": "string",
            "enum": ["usbl", "onboard_platform"],
            "description": "Indicate if this status message is from the"
            + " platform or USBL",
            "example": "usbl",
        },
        "transmission_mode": {
            "type": "string",
            "enum": ["acoustics", "iridium", "wifi", "starlink"],
            "description": "Mode in which status message was transmitted"
            + " when on the surface (e.g. iridium/wifi) or underwater"
            + " (e.g. acoustics)",
            "example": "wifi",
        },
        "platform_timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp for onboard platform status message",
            "example": "2022-12-21T00:00:00Z",
        },
        "platform_state": {
            "type": "string",
            "description": "Current state executed by platform. E.g. "
            + "STOP, IDLE, ABORT.",
            "example": "ABORT",
        },  # TODO: Define enum with potential STATES of each platform
        "autonomy_engine_plan_ID": {
            "type": "integer",
            "description": "Last mission plan ID (according to Autonomy"
            + " Engine's mission plan number sent) executed by platform",
            "example": 1,
        },
        "latitude": {
            "type": "number",
            "format": "float",
            "description": "Latitude (Y-coordinate) in decimal degrees.",
            "example": 178.2,
        },
        "longitude": {
            "type": "number",
            "format": "float",
            "description": "Longitude (X-coordinate) in decimal degrees.",
            "example": -10.122,
        },
        "depth": {
            "type": "number",
            "format": "float",
            "description": "Target depth in metres",
            "example": 50.0,
            "default": 0.0,
        },
        "altitude": {
            "type": "number",
            "format": "float",
            "description": "Target altitude in metres",
            "example": 20.0,
        },
        "mission_track_ID": {
            "type": "integer",
            "description": "Track number - stage in mission (e.g. "
            + "4 --> Waypoint 3 to Waypoint 4)",
            "example": 4,
        },
        "mission_plan_ID": {
            "type": "integer",
            "description": "Mission plan ID according to platform-C2 system",
            "example": 1,
        },
        "range_to_go": {
            "type": "number",
            "format": "float",
            "description": "Estimated distance to reach next waypoint",
            "example": 124.3,
        },
        "speed_over_ground": {
            "type": "number",
            "format": "float",
            "description": "Speed over ground",
            "example": 124.3,
        },
        "water_current_velocity": {
            "type": "string",
            "description": "Water current magnitude and direction",
            "example": "124.3NE",
        },
        "thrust_applied": {
            "type": "number",
            "format": "float",
            "description": "Thrust applied",
            "example": 124.3,
        },
        "heading": {
            "type": "number",
            "format": "float",
            "description": "Angular distance relative to north, usually 000°"
            + " at north, clockwise through 359°, in degrees",
            "example": 124.3,
        },
        "health_status": {
            "type": "boolean",
            "description": "Health status where 0 is OK, 1 is platform has"
            + " an ERROR",
            "example": False,
        },
        "localisation_north_error": {
            "type": "number",
            "format": "float",
            "description": "Difference in NORTH between deadreckoning"
            + " and USBL update.",
            "example": 0.000129,
        },
        "localisation_east_error": {
            "type": "number",
            "format": "float",
            "description": "Difference in EAST between deadreckoning"
            + "and USBL update.",
            "example": 0.000129,
        },
        "usbl_fix_seconds_ago": {
            "type": "number",
            "format": "float",
            "description": "USBL Fix received x second ago.",
            "example": 10.0,
        },
        "battery_remaining_capacity": {
            "type": "number",
            "format": "float",
            "description": "Battery remaining % provided by respective C2",
            "example": 80.2,
        },
        # Battery power (kw / float)
        "battery_output": {  # changed from battery_power
            "type": "number",
            "format": "float",
            "description": "Battery output in kW",
            "example": 80.2,
        },
        # Bunkers remaining capacity (litres, float)
        # Bunkers percentage full (percentage, float)
        # battery_remaining_capacity is % full if we want both these fields
        # these names are going to cause confusion
        "fuel_remaining_capacity": {
            "type": "number",
            "format": "float",
            "description": "Percentage remaining capacity",
            "example": 80.2,
        },
        "fuel_volume": {
            "type": "number",
            "format": "float",
            "description": "Litres of liquid fuel",
            "example": 12.5,
        },
        # Endurance (hours, float)
        "endurance": {
            "type": "number",
            "format": "float",
            "description": "Estimate of hours of operation remaining "
            + "based on present output or performance",
            "example": 7.4,
        },
        "sensor_config": sensor_schema,
    },
    "required": [
        "message_type",
        "platform_ID",
        "status_source",
        "platform_timestamp",
        "latitude",
        "longitude",
    ],
}

alert_schema = {
    "type": "object",
    "properties": {
        "message_type": {
            "type": "string",
            "description": "Type of message",
            "example": "alert",
            "enum": ["alert"],
        },
        "code": {  # changed from alert_ID because reasons
            "type": "integer",
            "description": "Alert code",
            "example": 345,
        },
        "platform_ID": {
            "type": "string",
            "description": "Unique identifier for this platform",
            "example": "usvdecibel",
        },
        "platform_timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp for onboard platform status message",
            "example": "2022-12-21T00:00:00Z",
        },
        "subsystem": {  # changed from suggested "source" could be device / subsystem or something
            "type": "string",
            "description": "System that generated the alert",
            "example": "Onboard Fault Monitor",
        },
        "summary": {
            "type": "string",
            "description": "High level description of the alert",
            "example": "Steering Damage - Port Side",
        },
        "details": {
            "type": "string",
            "description": "Detailed reason for the alert ",
            "example": "Discrepancy between rudder and actuator positions"
            + " : Rudder Pos=10.31°, Steering Actuator Pos=28.65°, Discrepancy=18.33°",
        },
        "severity": {
            "type": "string",
            "description": "Severity level of alert",
            "example": "Alarm",
            "enum": ["Emergency", "Alarm", "Warning", "Caution"],
        },
    },
    "required": [
        "message_type",
        "platform_ID",
        "code",
        "severity",
    ],
}