import gleam/dynamic/decode import gleam/json import gleam/list import gleam/option.{type Option} import models/construction.{type Construction} import models/jump_gate.{type JumpGate} import models/market.{type Market} import models/ship_cargo.{type ShipCargo} import models/ship_symbol.{type ShipSymbol} import models/shipyard.{type Shipyard} import models/system.{type System} import models/system_symbol.{type SystemSymbol} import models/trade_symbol.{type TradeSymbol} import models/waypoint.{type Waypoint} import models/waypoint_symbol.{type WaypointSymbol} import models/waypoint_trait_symbol.{type WaypointTraitSymbol} import models/waypoint_type.{type WaypointType} import utils/api.{type ApiResponse, type PagedData} import utils/auth.{type AgentToken, AgentAuth} pub fn list_systems( token: AgentToken, page: Option(Int), limit: Option(Int), ) -> ApiResponse(PagedData(List(System))) { let request = api.get_page(AgentAuth(token), "/systems", page, limit) use response <- api.try_send(request) case response.status { 200 -> api.parse_paged_data_response(response, decode.list(system.decoder())) _ -> api.parse_error_response(response) } } pub fn get_system( token: AgentToken, system_symbol: SystemSymbol, ) -> ApiResponse(System) { let request = api.get( AgentAuth(token), "/systems/" <> system_symbol.to_string(system_symbol), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, system.decoder()) _ -> api.parse_error_response(response) } } pub fn list_system_waypoints( token: AgentToken, system_symbol: SystemSymbol, page: Option(Int), limit: Option(Int), type_: Option(WaypointType), traits: List(WaypointTraitSymbol), ) -> ApiResponse(PagedData(List(Waypoint))) { let query = list.map(traits, fn(trait) { #("traits", waypoint_trait_symbol.to_string(trait)) }) let query = case type_ { option.Some(type_) -> [#("type", waypoint_type.to_string(type_)), ..query] option.None -> query } let request = api.get_page_with_query( AgentAuth(token), "/systems/" <> system_symbol.to_string(system_symbol) <> "/waypoints", page, limit, query, ) use response <- api.try_send(request) case response.status { 200 -> api.parse_paged_data_response(response, decode.list(waypoint.decoder())) _ -> api.parse_error_response(response) } } pub fn get_waypoint( token: AgentToken, system_symbol: SystemSymbol, waypoint_symbol: WaypointSymbol, ) -> ApiResponse(Waypoint) { let request = api.get( AgentAuth(token), "/systems/" <> system_symbol.to_string(system_symbol) <> "/waypoints/" <> waypoint_symbol.to_string(waypoint_symbol), ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, waypoint.decoder()) _ -> api.parse_error_response(response) } } pub fn get_construction_site( token: AgentToken, system_symbol: SystemSymbol, waypoint_symbol: WaypointSymbol, ) -> ApiResponse(Construction) { let request = api.get( AgentAuth(token), "/systems/" <> system_symbol.to_string(system_symbol) <> "/waypoints/" <> waypoint_symbol.to_string(waypoint_symbol) <> "/construction", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, construction.decoder()) _ -> api.parse_error_response(response) } } pub type ConstructionSiteSupplied { ConstructionSiteSupplied(construction: Construction, cargo: ShipCargo) } pub fn supply_construction_site( token: AgentToken, system_symbol: SystemSymbol, waypoint_symbol: WaypointSymbol, ship_symbol: ShipSymbol, trade_symbol: TradeSymbol, units: Int, ) -> ApiResponse(ConstructionSiteSupplied) { let request = api.post_json( AgentAuth(token), "/systems/" <> system_symbol.to_string(system_symbol) <> "/waypoints/" <> waypoint_symbol.to_string(waypoint_symbol) <> "/construction/supply", json.object([ #("shipSymbol", ship_symbol.encode(ship_symbol)), #("tradeSymbol", trade_symbol.encode(trade_symbol)), #("units", json.int(units)), ]), ) use response <- api.try_send(request) case response.status { 201 -> api.parse_data_response(response, { use construction <- decode.field("construction", construction.decoder()) use cargo <- decode.field("cargo", ship_cargo.decoder()) decode.success(ConstructionSiteSupplied(construction:, cargo:)) }) _ -> api.parse_error_response(response) } } pub fn get_market( token: AgentToken, system_symbol: SystemSymbol, waypoint_symbol: WaypointSymbol, ) -> ApiResponse(Market) { let request = api.get( AgentAuth(token), "/systems/" <> system_symbol.to_string(system_symbol) <> "/waypoints/" <> waypoint_symbol.to_string(waypoint_symbol) <> "/market", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, market.decoder()) _ -> api.parse_error_response(response) } } pub fn get_jump_gate( token: AgentToken, system_symbol: SystemSymbol, waypoint_symbol: WaypointSymbol, ) -> ApiResponse(JumpGate) { let request = api.get( AgentAuth(token), "/systems/" <> system_symbol.to_string(system_symbol) <> "/waypoints/" <> waypoint_symbol.to_string(waypoint_symbol) <> "/jump-gate", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, jump_gate.decoder()) _ -> api.parse_error_response(response) } } pub fn get_shipyard( token, system_symbol, waypoint_symbol, ) -> ApiResponse(Shipyard) { let request = api.get( AgentAuth(token), "/systems/" <> system_symbol <> "/waypoints/" <> waypoint_symbol <> "/shipyard", ) use response <- api.try_send(request) case response.status { 200 -> api.parse_data_response(response, shipyard.decoder()) _ -> api.parse_error_response(response) } }