syntax = "proto3";

package geoip2;

service GeoIp {
  rpc Lookup(Message) returns (CityReply) {}
  rpc Metadata(Empty) returns (MetadataReply) {}
  rpc Reload(Empty) returns (MetadataReply) {}
}

message Empty {}

message Message {
  string ip = 1;
  enum Locale {
    UNSPECIFIED = 0;
    BRAZLIAN_PORTUGUESE = 1;
    ENGLISH = 2;
    FRENCH = 3;
    GERMAN = 4;
    JAPANESE = 5;
    RUSSIAN = 6;
    SIMPLIFIED_CHINESE = 7;
    SPANISH = 8;
  }
  repeated Locale locales = 2;
}

/**
 * CityReply represents MaxMind's GeoLite2 databases.
 * See https://docs.rs/maxminddb/0.13.0/maxminddb/geoip2/struct.City.html
 */
message CityReply {
  oneof city_option {
    City city = 1;
  }
  oneof continent_option {
    Continent continent = 2;
  }
  oneof country_option {
    Country country = 3;
  }
  oneof location_option {
    Location location = 4;
  }
  oneof postal_option {
    Postal postal = 5;
  }
  oneof registered_country_option {
    Country registered_country = 6;
  }
  oneof represented_country_option {
    RepresentedCountry represented_country = 7;
  }
  repeated Subdivision subdivisions = 8;
  oneof traits_option {
    Traits traits = 9;
  }
}

message City {
  oneof geoname_id_option {
    uint32 geoname_id = 1;
  }
  map<string, string> names = 2;
}

message Continent {
  oneof code_option {
    string code = 1;
  }
  oneof geoname_id_option {
    uint32 geoname_id = 2;
  }
  map<string, string> names = 3;
}

message Country {
  oneof geoname_id_option {
    uint32 geoname_id = 1;
  }
  bool is_in_european_union = 2;
  oneof iso_code_option {
    string iso_code = 3;
  }
  map<string, string> names = 4;
}

message Location {
  oneof latitude_option {
    double latitude = 1;
  }
  oneof longitude_option {
    double longitude = 2;
  }
  oneof metro_code_option {
    uint32 metro_code = 3;
  }
  oneof time_zone_option {
    string time_zone = 4;
  }
}

message Postal {
  oneof code_option {
    string code = 1;
  }
}

message RepresentedCountry {
  oneof geoname_id_option {
    uint32 geoname_id = 1;
  }
  oneof iso_code_option {
    string iso_code = 2;
  }
  map<string, string> names = 3;
}

message Subdivision {
  oneof geoname_id_option {
    uint32 geoname_id = 1;
  }
  oneof iso_code_option {
    string iso_code = 2;
  }
  map<string, string> names = 3;
}

message Traits {
  bool is_anonymous_proxy = 1;
  bool is_satellite_provider = 2;
}

message MetadataReply {
  uint32 binary_format_major_version = 1;
  uint32 binary_format_minor_version = 2;
  uint64 build_epoch = 3;
  string database_type = 4;
  map<string, string> description = 5;
  uint32 ip_version = 6;
  repeated string languages = 7;
  uint32 node_count = 8;
  uint32 record_size = 9;
}
