summaryrefslogtreecommitdiff
path: root/haskell/src/SpaceTraders/APIClient/Ships.hs
blob: 912f6e81265732baef8f7e45ac75a18d940bc643 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE OverloadedStrings #-}

module SpaceTraders.APIClient.Ships
  ( dock
  , myShips
  , orbit
  , refuel
  ) where

import           Data.Aeson.Types
import qualified Data.Text.Encoding                as T
import           GHC.Generics
import           Network.HTTP.Simple

import           SpaceTraders
import           SpaceTraders.APIClient.Client
import           SpaceTraders.APIClient.Pagination
import           SpaceTraders.Database.Agents
import           SpaceTraders.Database.Ships
import qualified SpaceTraders.Model.Agent
import           SpaceTraders.Model.Fuel
import           SpaceTraders.Model.Nav
import           SpaceTraders.Model.Ship

newtype NavMessage = NavMessage { nav :: Nav } deriving (FromJSON, Generic, Show)

dock :: Ship -> SpaceTradersT (APIResponse Ship)
dock ship = if isDocked ship then pure (Right ship) else dock'
  where
    dock' = do
      resp <- send $ setRequestPath (T.encodeUtf8 $ mconcat ["/v2/my/ships/", symbol ship, "/dock"])
                   . setRequestMethod "POST" :: SpaceTradersT (APIResponse NavMessage)
      case resp of
        Left e -> return $ Left e
        Right (NavMessage n) -> do
          let s = ship{SpaceTraders.Model.Ship.nav=n}
          setShip s
          return $ Right s

myShips :: SpaceTradersT (APIResponse [Ship])
myShips = do
  listShips' Pagination{limit=20, page=1, total=0}
  where
    listShips' :: Pagination -> SpaceTradersT (APIResponse [Ship])
    listShips' p = do
      resp <- sendPaginated (Just p) $ setRequestPath "/v2/my/ships" :: SpaceTradersT (APIPaginatedResponse [Ship])
      case resp of
        Left e -> return $ Left e
        Right (APIMessage r (Just p')) -> do
          mapM_ setShip r
          if limit p' * page p' < total p' then listShips' (nextPage p')
                                           else Right <$> getShips
        _ -> undefined

orbit :: Ship -> SpaceTradersT (APIResponse Ship)
orbit ship = if isInOrbit ship then pure (Right ship) else orbit'
  where
    orbit' = do
      resp <- send $ setRequestPath (T.encodeUtf8 $ mconcat ["/v2/my/ships/", symbol ship, "/orbit"])
                   . setRequestMethod "POST" :: SpaceTradersT (APIResponse NavMessage)
      case resp of
        Left e -> return $ Left e
        Right (NavMessage n) -> do
          let s = ship{SpaceTraders.Model.Ship.nav=n}
          setShip s
          return $ Right s

data RefuelMessage = RefuelMessage { agent :: SpaceTraders.Model.Agent.Agent
                                   , fuel  :: Fuel
                                   } deriving (FromJSON, Generic, Show)

refuel :: Ship -> SpaceTradersT (APIResponse Ship)
refuel ship = if overNinetyPercentFuel ship then pure (Right ship) else refuel'
  where
    refuel' = do
      resp <- dock ship
      case resp of
        (Left e)      -> return $ Left e
        (Right ship') -> refuel'' ship'
    refuel'' ship' = do
      -- TODO check if we are at a marketplace, that sells fuel
      resp' <- send $ setRequestPath (T.encodeUtf8 $ mconcat ["/v2/my/ships/", symbol ship, "/refuel"])
                    . setRequestMethod "POST" :: SpaceTradersT (APIResponse RefuelMessage)
      case resp' of
        Left e -> return $ Left e
        Right (RefuelMessage a f) -> do
          setAgent a
          let s = ship'{SpaceTraders.Model.Ship.fuel=f}
          setShip s
          return $ Right s