"""Data types and operations from Geospatial Map Provider Automated Testing Interface 0.2.0 OpenAPI"""

# This file is autogenerated; do not modify manually!

from __future__ import annotations

from enum import Enum
from typing import Dict, List, Optional

from uas_standards import Operation

from implicitdict import ImplicitDict, StringBasedDateTime


API_VERSION = "0.2.0"
"""Version of Geospatial Map Provider Automated Testing Interface OpenAPI specification from which the objects in this package were generated."""

UUIDv4Format = str
"""String whose format matches a version-4 UUID according to RFC 4122."""


class StatusResponseStatus(str, Enum):
    """The status of the USS automated testing interface.
    - `Starting`: the USS is starting and the automated test driver should wait before sending requests.
    - `Ready`: the USS is ready to receive test requests.
    """

    Starting = "Starting"
    Ready = "Ready"


class StatusResponse(ImplicitDict):
    status: StatusResponseStatus
    """The status of the USS automated testing interface.
    - `Starting`: the USS is starting and the automated test driver should wait before sending requests.
    - `Ready`: the USS is ready to receive test requests.
    """

    api_name: Optional[str]
    """Indication of the API implemented at this URL.  Must be "Geospatial Map Provider Automated Testing Interface"."""

    api_version: Optional[str]
    """Indication of the API version implemented at this URL.  Must be "v0.2.0" when implementing this version of the API."""


class GeospatialHttpsSourceFormat(str, Enum):
    """The format of the response expected from the source."""

    ED_269 = "ED-269"


class GeospatialHttpsSource(ImplicitDict):
    url: str
    """The URL at which the Geospatial data shall be downloaded from."""

    format: Optional[GeospatialHttpsSourceFormat] = GeospatialHttpsSourceFormat.ED_269
    """The format of the response expected from the source."""


class GeospatialDataSourceStatusStatus(str, Enum):
    """The status of the Geospatial source and the handling of its data by the USS.
    - `Activating`: the USS is processing the request and is currently activating the geospatial data.
    - `Ready`: the geospatial data has been successfully activated and the USS is ready to receive test requests.
    - `Deactivating`: the geospatial dataset is being deactivated.
    - `Deactivated`: the geospatial dataset has been deactivated (the USS may instead return 404 as well).
    - `Unsupported`: the USS cannot process the dataset type specified, or some valid feature within the dataset. The message field is required in this case.
    - `Rejected`: the geospatial data source was rejected because it failed content validation or was otherwise unsuitable to use. The message field is required in this case.
    - `Error`: the geospatial data activation or deactivation failed for a reason not covered by one of the previous options. The message field is required in this case.
    """

    Activating = "Activating"
    Ready = "Ready"
    Deactivating = "Deactivating"
    Deactivated = "Deactivated"
    Unsupported = "Unsupported"
    Rejected = "Rejected"
    Error = "Error"


class GeospatialDataSourceStatus(ImplicitDict):
    id: UUIDv4Format
    """ID of this geospatial data source"""

    status: GeospatialDataSourceStatusStatus
    """The status of the Geospatial source and the handling of its data by the USS.
    - `Activating`: the USS is processing the request and is currently activating the geospatial data.
    - `Ready`: the geospatial data has been successfully activated and the USS is ready to receive test requests.
    - `Deactivating`: the geospatial dataset is being deactivated.
    - `Deactivated`: the geospatial dataset has been deactivated (the USS may instead return 404 as well).
    - `Unsupported`: the USS cannot process the dataset type specified, or some valid feature within the dataset. The message field is required in this case.
    - `Rejected`: the geospatial data source was rejected because it failed content validation or was otherwise unsuitable to use. The message field is required in this case.
    - `Error`: the geospatial data activation or deactivation failed for a reason not covered by one of the previous options. The message field is required in this case.
    """

    message: Optional[str]
    """Human-readable explanation of the result for debugging purpose only. This field is required when the result value is `Error`."""


class GeospatialDataSourceResponse(ImplicitDict):
    data_source: GeospatialDataSourceStatus


class ListGeospatialDataSourcesResponse(ImplicitDict):
    data_sources: Optional[List[GeospatialDataSourceStatus]]


class GeospatialFeatureFilterSetResultingOperationalImpact(str, Enum):
    """If specified, only select geospatial features that would cause the specified outcome if a user attempted to plan a flight applicable to all the other criteria in this filter set.
    'Block': The geospatial feature would cause rejection of that flight (the USS would decline to plan the
      flight).

    'Advise': The geospatial feature would cause the USS to accompany a successful flight plan (if the flight
      was successfully planned) with an advisory or condition provided to the operator.

    'BlockOrAdvise': The geospatial feature would cause one of 'Block' or 'Advise' to be be true.
    """

    Block = "Block"
    Advise = "Advise"
    BlockOrAdvise = "BlockOrAdvise"


class GeospatialMapCheckResultFeaturesSelectionOutcome(str, Enum):
    """Indication of whether one or more applicable geospatial features were selected according to the selection criteria of the corresponding check.
    - `Present`: One or more applicable geospatial features were selected.
    - `Absent`: No applicable geospatial features were selected.
    - `UnsupportedFilter`: Applicable geospatial features could not be selected because one or more filter criteria are not supported by the USS.  If this value is specified, `message` must be populated.
    - `Error`: An error or condition not enumerated above occurred.  If this value is specified, `message` must be populated.
    """

    Present = "Present"
    Absent = "Absent"
    UnsupportedFilter = "UnsupportedFilter"
    Error = "Error"


class GeospatialMapCheckResult(ImplicitDict):
    features_selection_outcome: Optional[GeospatialMapCheckResultFeaturesSelectionOutcome]
    """Indication of whether one or more applicable geospatial features were selected according to the selection criteria of the corresponding check.
    - `Present`: One or more applicable geospatial features were selected.
    - `Absent`: No applicable geospatial features were selected.
    - `UnsupportedFilter`: Applicable geospatial features could not be selected because one or more filter criteria are not supported by the USS.  If this value is specified, `message` must be populated.
    - `Error`: An error or condition not enumerated above occurred.  If this value is specified, `message` must be populated.
    """

    message: Optional[str]
    """A human-readable description of why the unsuccessful `featuresSelectionOutcome` was reported.  Should only be populated when appropriate according to the value of the `featuresSelectionOutcome` field."""


class AltitudeReference(str, Enum):
    """A code indicating the reference for a vertical distance. See AIXM 5.1 and FIXM 4.2.0."""

    W84 = "W84"
    SFC = "SFC"


class AltitudeUnits(str, Enum):
    """The reference quantities used to express the value of altitude. See FIXM 4.2."""

    M = "M"
    FT = "FT"


class Altitude(ImplicitDict):
    value: float
    """The numeric value of the altitude. Note that min and max values are added as a sanity check. As use cases evolve and more options are made available in terms of units of measure or reference systems, these bounds may be re-evaluated."""

    reference: AltitudeReference
    """A code indicating the reference for a vertical distance. See AIXM 5.1 and FIXM 4.2.0."""

    units: AltitudeUnits
    """The reference quantities used to express the value of altitude. See FIXM 4.2."""


Longitude = float
"""Degrees of longitude east of the Prime Meridian, with reference to the WGS84 ellipsoid."""


Latitude = float
"""Degrees of latitude north of the equator, with reference to the WGS84 ellipsoid."""


class RadiusUnits(str, Enum):
    """FIXM-compatible units.  Only meters ("M") are acceptable for UTM."""

    M = "M"


class Radius(ImplicitDict):
    value: float
    """Distance from the centerpoint of a circular area, along the WGS84 ellipsoid."""

    units: RadiusUnits = RadiusUnits.M
    """FIXM-compatible units.  Only meters ("M") are acceptable for UTM."""


class TimeFormat(str, Enum):
    RFC3339 = "RFC3339"


class Time(ImplicitDict):
    value: StringBasedDateTime
    """RFC3339-formatted time/date string.  The time zone must be 'Z'."""

    format: TimeFormat = TimeFormat.RFC3339


USpaceClass = str


class Restriction(str, Enum):
    PROHIBITED = "PROHIBITED"
    REQ_AUTHORISATION = "REQ_AUTHORISATION"
    CONDITIONAL = "CONDITIONAL"
    NO_RESTRICTION = "NO_RESTRICTION"


class CreateGeospatialDataSourceRequest(ImplicitDict):
    https_source: Optional[GeospatialHttpsSource]


class ED269Filters(ImplicitDict):
    """Filter criteria for the selection of Geozones according to ED-269 characteristics."""

    u_space_class: Optional[USpaceClass]
    """If specified, only select Geozones which are of the specified `u_space_class`."""

    acceptable_restrictions: Optional[List[Restriction]]
    """If specified and non-empty, only select Geozones which are one of the specified restriction types."""


class GeospatialMapQueryReply(ImplicitDict):
    results: Optional[List[GeospatialMapCheckResult]] = []
    """Responses to each of the `checks` in the request.  The number of entries in this array should match the number of entries in the `checks` field of the request."""


class LatLngPoint(ImplicitDict):
    """Point on the earth's surface."""

    lng: Longitude

    lat: Latitude


class Circle(ImplicitDict):
    """A circular area on the surface of the earth."""

    center: Optional[LatLngPoint]

    radius: Optional[Radius]


class Polygon(ImplicitDict):
    """An enclosed area on the earth. The bounding edges of this polygon are defined to be the shortest paths between connected vertices.  This means, for instance, that the edge between two points both defined at a particular latitude is not generally contained at that latitude. The winding order must be interpreted as the order which produces the smaller area. The path between two vertices is defined to be the shortest possible path between those vertices. Edges may not cross. Vertices may not be duplicated.  In particular, the final polygon vertex must not be identical to the first vertex."""

    vertices: List[LatLngPoint]


class Position(ImplicitDict):
    altitude: Optional[Altitude]
    """Position's height above a vertical reference datum."""

    location: LatLngPoint
    """Position's horizontal (along Earth's surface) location."""


class Volume3D(ImplicitDict):
    """A three-dimensional geographic volume consisting of a vertically-extruded shape. Exactly one outline must be specified."""

    outline_circle: Optional[Circle]
    """A circular geographic shape on the surface of the earth."""

    outline_polygon: Optional[Polygon]
    """A polygonal geographic shape on the surface of the earth."""

    altitude_lower: Optional[Altitude]
    """Minimum bounding altitude of this volume. Must be less than altitude_upper, if specified."""

    altitude_upper: Optional[Altitude]
    """Maximum bounding altitude of this volume. Must be greater than altitude_lower, if specified."""


class Volume4D(ImplicitDict):
    """Contiguous block of geographic spacetime."""

    volume: Volume3D

    time_start: Optional[Time]
    """Beginning time of this volume. Must be before time_end."""

    time_end: Optional[Time]
    """End time of this volume. Must be after time_start."""


class GeospatialFeatureFilterSet(ImplicitDict):
    """Set of filters to select only a subset of geospatial features.  Only geospatial features which are applicable to all specified filters within this filter set should be selected."""

    position: Optional[Position]
    """If specified, only select geospatial features encompassing this position."""

    volumes4d: Optional[List[Volume4D]]
    """If specified, only select geospatial features at least partially intersecting one or more of these volumes."""

    after: Optional[StringBasedDateTime]
    """If specified, only select geospatial features which encompass at least some times at or after this time."""

    before: Optional[StringBasedDateTime]
    """If specified, only select geospatial features which encompass at least some times at or before this time."""

    restriction_source: Optional[str]
    """If specified, only select geospatial features originating from the named source.  The acceptable values for this field will be established by the test designers and will generally be used to limit responses to only the intended datasets under test even when the USS may have more additional geospatial features from other sources that may otherwise be relevant."""

    operation_rule_set: Optional[str]
    """If specified, only select geospatial features that would be relevant when planning an operation under the specified rule set.  The acceptable values for this field will be established by the test designers and will generally correspond to sets of rules under which the system under test plans operations."""

    resulting_operational_impact: Optional[GeospatialFeatureFilterSetResultingOperationalImpact]
    """If specified, only select geospatial features that would cause the specified outcome if a user attempted to plan a flight applicable to all the other criteria in this filter set.
    'Block': The geospatial feature would cause rejection of that flight (the USS would decline to plan the
      flight).

    'Advise': The geospatial feature would cause the USS to accompany a successful flight plan (if the flight
      was successfully planned) with an advisory or condition provided to the operator.

    'BlockOrAdvise': The geospatial feature would cause one of 'Block' or 'Advise' to be be true.
    """

    ed269: Optional[ED269Filters]


class GeospatialMapCheck(ImplicitDict):
    filter_sets: Optional[List[GeospatialFeatureFilterSet]]
    """Select geospatial features which match any of the specified filter sets."""


class GeospatialMapQueryRequest(ImplicitDict):
    checks: List[GeospatialMapCheck]


class OperationID(str, Enum):
    GetStatus = "GetStatus"
    ListGeospatialDataSources = "ListGeospatialDataSources"
    PutGeospatialDataSource = "PutGeospatialDataSource"
    GetGeospatialDataSourceStatus = "GetGeospatialDataSourceStatus"
    DeleteGeospatialDataSource = "DeleteGeospatialDataSource"
    QueryGeospatialMap = "QueryGeospatialMap"


OPERATIONS: Dict[OperationID, Operation] = {
    OperationID.GetStatus: Operation(
        id="GetStatus",
        path="/status",
        verb="GET",
        request_body_type=None,
        response_body_type={
            200: StatusResponse,
            401: None,
            403: None,
            404: None,
        }
    ),
    OperationID.ListGeospatialDataSources: Operation(
        id="ListGeospatialDataSources",
        path="/geospatial_data_sources",
        verb="GET",
        request_body_type=None,
        response_body_type={
            200: ListGeospatialDataSourcesResponse,
            401: None,
            403: None,
        }
    ),
    OperationID.PutGeospatialDataSource: Operation(
        id="PutGeospatialDataSource",
        path="/geospatial_data_sources/{geospatial_data_source_id}",
        verb="PUT",
        request_body_type=CreateGeospatialDataSourceRequest,
        response_body_type={
            200: GeospatialDataSourceResponse,
            401: None,
            403: None,
            409: None,
        }
    ),
    OperationID.GetGeospatialDataSourceStatus: Operation(
        id="GetGeospatialDataSourceStatus",
        path="/geospatial_data_sources/{geospatial_data_source_id}",
        verb="GET",
        request_body_type=None,
        response_body_type={
            200: GeospatialDataSourceResponse,
            401: None,
            403: None,
            404: None,
        }
    ),
    OperationID.DeleteGeospatialDataSource: Operation(
        id="DeleteGeospatialDataSource",
        path="/geospatial_data_sources/{geospatial_data_source_id}",
        verb="DELETE",
        request_body_type=None,
        response_body_type={
            200: GeospatialDataSourceResponse,
            401: None,
            403: None,
        }
    ),
    OperationID.QueryGeospatialMap: Operation(
        id="QueryGeospatialMap",
        path="/map/queries",
        verb="POST",
        request_body_type=GeospatialMapQueryRequest,
        response_body_type={
            200: GeospatialMapQueryReply,
            401: None,
            403: None,
        }
    ),
}
