-- This function simulates running the actions, and returns the final state,
-- together with a list of all actions that would have been performed. Some
-- actions require input from the outside world. Simulating these actions will
-- return the pushResult and rebaseResult passed in here.
runActionWithInit :: Maybe Sha -> PushResult -> [ActionFlat] -> Action a -> (a, [ActionFlat])
runActionWithInit integrateResult pushResult actions action =
  let
    prepend cont act =
      let (result, acts') = runActionWithInit integrateResult pushResult actions cont
      in  (result, act : acts')
  in
    case action of
      Pure result                          -> (result, [])
      Free (TryIntegrate msg candi h)      -> prepend (h integrateResult) $ ATryIntegrate msg candi
      Free (TryPromote prBranch headSha h) -> prepend (h pushResult) $ ATryPromote prBranch headSha
      Free (LeaveComment pr body x)        -> prepend x $ ALeaveComment pr body

-- Simulates running the action. Pretends that integration always conflicts.
-- Pretends that pushing is always successful.
runActionWithInit :: Maybe Sha -> PushResult -> [ActionFlat] -> Action a -> (a, [ActionFlat])
runActionWithInit integrateResult pushResult actions action =
  let
    prepend cont act =
      let (result, acts') = runActionWithInit integrateResult pushResult actions cont
      in  (result, act : acts')
  in
    case action of
      Pure result                          -> (result, [])
      Free (TryIntegrate msg candi h)      -> prepend (h integrateResult) $ ATryIntegrate msg candi
      Free (TryPromote prBranch headSha h) -> prepend (h pushResult) $ ATryPromote prBranch headSha
      Free (LeaveComment pr body x)        -> prepend x $ ALeaveComment pr body

-- Simulates running the action. Pretends that integration always conflicts.
-- Pretends that pushing is always successful.
runActionWithInit integrateResult pushResult actions action =
  let
    prepend cont act =
      let (result, acts') = runActionWithInit integrateResult pushResult actions cont
      in  (result, act : acts')
  in
    case action of
      Pure result                          -> (result, [])
      Free (TryIntegrate msg candi h)      -> prepend (h integrateResult) $ ATryIntegrate msg candi
      Free (TryPromote prBranch headSha h) -> prepend (h pushResult) $ ATryPromote prBranch headSha
      Free (LeaveComment pr body x)        -> prepend x $ ALeaveComment pr body

-- Simulates running the action. Pretends that integration always conflicts.
-- Pretends that pushing is always successful.