module Buffet.Parse.PartitionByBuildStage
  ( get
  ) where

import qualified Data.List.Split as Split
import qualified Language.Docker as Docker
import Prelude (Bool(False, True), ($), length, mconcat, pred, splitAt)

get ::
     Docker.Dockerfile
  -> (Docker.Dockerfile, [Docker.Dockerfile], Docker.Dockerfile)
get :: Dockerfile -> (Dockerfile, [Dockerfile], Dockerfile)
get Dockerfile
dockerfile = (Dockerfile
beforeFirstStage, [Dockerfile]
localStages, Dockerfile
globalStage)
  where
    (Dockerfile
beforeFirstStage, [Dockerfile]
stages) =
      case [Dockerfile]
parts of
        [] -> ([], [])
        (Dockerfile
first:[Dockerfile]
rest) -> (Dockerfile
first, [Dockerfile]
rest)
    parts :: [Dockerfile]
parts = Splitter (InstructionPos Text) -> Dockerfile -> [Dockerfile]
forall a. Splitter a -> [a] -> [[a]]
Split.split Splitter (InstructionPos Text)
forall a. Splitter (InstructionPos a)
splitter Dockerfile
dockerfile
    splitter :: Splitter (InstructionPos a)
splitter = Splitter (InstructionPos a) -> Splitter (InstructionPos a)
forall a. Splitter a -> Splitter a
Split.keepDelimsL (Splitter (InstructionPos a) -> Splitter (InstructionPos a))
-> Splitter (InstructionPos a) -> Splitter (InstructionPos a)
forall a b. (a -> b) -> a -> b
$ (InstructionPos a -> Bool) -> Splitter (InstructionPos a)
forall a. (a -> Bool) -> Splitter a
Split.whenElt InstructionPos a -> Bool
forall a. InstructionPos a -> Bool
isFrom
    ([Dockerfile]
localStages, [Dockerfile]
globalStageInstructions) =
      Int -> [Dockerfile] -> ([Dockerfile], [Dockerfile])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int -> Int
forall a. Enum a => a -> a
pred (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ [Dockerfile] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Dockerfile]
stages) [Dockerfile]
stages
    globalStage :: Dockerfile
globalStage = [Dockerfile] -> Dockerfile
forall a. Monoid a => [a] -> a
mconcat [Dockerfile]
globalStageInstructions

isFrom :: Docker.InstructionPos a -> Bool
isFrom :: InstructionPos a -> Bool
isFrom (Docker.InstructionPos (Docker.From BaseImage
_) Text
_ Int
_) = Bool
True
isFrom InstructionPos a
_ = Bool
False