syntax = "proto3";
// NOTE: the optional keyword doesn't mean it's nullable, but for presence tracking which forces the field to be explicitly sent

enum Service {
    PASSENGER = 0;
    CARGO = 1;
    MILITARY_AND_GOVERNMENT = 2;
    BUSINESS_JETS = 3;
    GENERAL_AVIATION = 4;
    HELICOPTERS = 5;
    LIGHTER_THAN_AIR = 6;
    GLIDERS = 7;
    DRONES = 8;
    GROUND_VEHICLES = 9;
    OTHER_SERVICE = 10;
    NON_CATEGORIZED = 11;
}

enum DataSource {
    ADSB = 0;
    MLAT = 1;
    FLARM = 2;
    FAA = 3;
    ESTIMATED = 4;
    SATELLITE = 5;
    OTHER_DATA_SOURCE = 6;
    UAT = 7;
    SPIDERTRACKS = 8;
    AUS = 9;
}

message FiltersList {
    message AltitudeRange {
        int32 min = 1;
        int32 max = 2;
    } // feet

    message SpeedRange {
        int32 min = 1;
        int32 max = 2;
    } // knots

    message AirlineFilter {
        enum Type {
            PAINTED_AS = 0;
            OPERATED_AS = 1;
        }
        string icao = 1; // e.g. CPA
        Type type = 2;
    }

    message AirportFilter {
        enum Type {
            BOTH = 0;
            INBOUND = 1;
            OUTBOUND = 2;
        }
        string iata = 1;
        int32 country_id = 2;
        Type type = 3;
    }

    message BirthYearRange {
        int32 min = 1;
        int32 max = 2;
    }

    message ODFilter {
        string iata = 1;
        int32 country_id = 2;
    }

    repeated AltitudeRange altitude_ranges_list = 1;
    repeated SpeedRange speed_ranges_list = 2; // NOTE: ground speed
    repeated AirlineFilter airline_filters_list = 3;
    repeated string callsigns_list = 4;
    repeated string radars_list = 5; // receiver: e.g. T-VHST000
    repeated string regs_list = 6;
    repeated AirportFilter airports_list = 7;
    // repeated Flight flights_list = 8;
    repeated string types_list = 9; // e.g. B7*
    repeated BirthYearRange birth_year_ranges_list = 10;
    // repeated Squawk squawks_list = 11;
    repeated ODFilter origins_list = 12;
    repeated ODFilter destinations_list = 13;
    repeated Service categories_list = 14;
}

message LiveFeedRequest {
    message Bounds {
        float north = 1;
        float south = 2;
        float west = 3;
        float east = 4;
    }

    message Settings {
        enum TrafficType {
            NONE = 0;
            GROUND_ONLY = 1;
            AIRBORNE_ONLY = 2;
            ALL = 3;
        }

        repeated DataSource sources_list = 1;
        repeated Service services_list = 2;
        TrafficType traffic_type = 3;
        optional bool only_restricted = 4;
    }

    message FieldMask {
        repeated string field_name = 1;
    }

    enum RestrictionMode {
        NOT_VISIBLE = 0;
        RESTRICTED_INCLUDED = 1;
        RESTRICTED_ONLY = 2;
    }

    Bounds bounds = 1;
    Settings settings = 2;
    FiltersList filters_list = 3;
    string custom_fleet_id = 4; // requires auth
    bool highlight_mode = 5;
    optional bool stats = 6;
    optional int32 limit = 7; // default 1500
    optional int32 maxage = 8; // default 14400
    optional RestrictionMode restriction_mode = 9;
    FieldMask field_mask = 10;
    repeated fixed32 selected_flightid = 11;
}

message LiveFeedResponse {
    message FlightData {
        message ExtraInfo {
            message Route {
                string from_ = 1;
                string to = 2;
            }

            message Schedule {
                int32 std = 1;
                int32 etd = 2;
                int32 atd = 3;
                int32 sta = 4;
                int32 eta = 5; //!
                int32 ata = 6;
            }

            // a =? altitude
            message EMS {
                int32 qnh = 1; // often null
                int32 amcp = 2; // likely barometric altitude
                int32 afms = 3; // often null
                int32 oat = 4;
                int32 ias = 5;
                int32 tas = 6;
                int32 mach = 7; // NOTE: 1000 = mach 1
                int32 agps = 8;
                int32 agpsdiff = 9; // |amcp - agps|
                int32 apflags = 10; // often null
                int32 wind_dir = 11;
                int32 wind_speed = 12;
                int32 rs = 13; // unknown
            }

            message EMSAvailability {
                bool qnh_availability = 1;
                bool amcp_availability = 2;
                bool afms_availability = 3;
                bool oat_availability = 4;
                bool ias_availability = 5;
                bool tas_availability = 6;
                bool mach_availability = 7;
                bool agps_availability = 8;
                bool agpsdiff_availability = 9;
                bool apflags_availability = 10;
                bool wind_dir_availability = 11;
                bool wind_speed_availability = 12;
                bool rs_availability = 13;
            }
            
            string flight = 1; // iata flight number
            string reg = 2;
            Route route = 3;
            string type = 4;
            int32 squawk = 5; // NOTE: 20852 -> 0x5174
            int32 vspeed = 6;
            string ac_birthday = 7; // aircraft age, in years
            int32 country_of_reg = 8;
            Schedule schedule = 9;
            int32 logo_id = 10; // u32
            int32 airspace = 11; // FIR
            EMS ems_info = 12;
            EMSAvailability ems_availability = 13;
            int32 icao_address = 14;
            // 15-18 are unknown int32s (only when flight is selected)
        }
        int32 flightid = 1; // to hex
        float latitude = 2;
        float longitude = 3;
        int32 heading = 4;
        int32 altitude = 5;
        int32 ground_speed = 6;
        int32 icon = 7;
        int32 status = 8;
        int32 timestamp = 9;
        bool on_ground = 10;
        string callsign = 11;
        DataSource source = 12;
        ExtraInfo extra_info = 13;
    }

    message Statistics {
        message SourceKV {
            DataSource source = 1;
            int32 count = 2;
        }

        repeated SourceKV sources = 1;
    }

    repeated FlightData flights_list = 1;
    Statistics stats = 2;
    repeated FlightData selected_flight_info = 3;
}

// duration: floor(7.5*(multiplier)) seconds, i.e. 1x = 7s
message LiveFeedPlaybackRequest {
    LiveFeedRequest live_feed_request = 1;
    int32 timestamp = 2; // 1x: 7 second intervals
    int32 prefetch = 3;
    optional int32 hfreq = 4;
}

message LiveFeedPlaybackResponse {
    LiveFeedResponse live_feed_response = 1;
}