module Buffet.Assemble.InsertOptionArgInstructionUnlessPresent
  ( get
  ) where

import qualified Buffet.Assemble.HasArgInstructionWithName as HasArgInstructionWithName
import qualified Buffet.Ir.Ir as Ir
import qualified Data.List as List
import qualified Language.Docker as Docker
import Prelude (Bool(False, True), Maybe(Nothing), (<>), span)

get :: Ir.Option -> Ir.DockerfilePart -> Ir.DockerfilePart
get :: Option -> DockerfilePart -> DockerfilePart
get Option
option DockerfilePart
stage = DockerfilePart
firstFroms DockerfilePart -> DockerfilePart -> DockerfilePart
forall a. Semigroup a => a -> a -> a
<> DockerfilePart
preparedAfterFirstFroms
  where
    (DockerfilePart
firstFroms, DockerfilePart
afterFirstFroms) = (Instruction Text -> Bool)
-> DockerfilePart -> (DockerfilePart, DockerfilePart)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Instruction Text -> Bool
forall a. Instruction a -> Bool
isFrom DockerfilePart
stage
    preparedAfterFirstFroms :: DockerfilePart
preparedAfterFirstFroms =
      if Option -> DockerfilePart -> Bool
HasArgInstructionWithName.get Option
option DockerfilePart
afterFirstFroms
        then DockerfilePart
afterFirstFroms
        else Instruction Text -> DockerfilePart -> DockerfilePart
forall a. Ord a => a -> [a] -> [a]
List.insert Instruction Text
forall args. Instruction args
arg DockerfilePart
firstArgs DockerfilePart -> DockerfilePart -> DockerfilePart
forall a. Semigroup a => a -> a -> a
<> DockerfilePart
afterFirstArgs
    arg :: Instruction args
arg = Text -> Maybe Text -> Instruction args
forall args. Text -> Maybe Text -> Instruction args
Docker.Arg (Option -> Text
Ir.option Option
option) Maybe Text
forall a. Maybe a
Nothing
    (DockerfilePart
firstArgs, DockerfilePart
afterFirstArgs) = (Instruction Text -> Bool)
-> DockerfilePart -> (DockerfilePart, DockerfilePart)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Instruction Text -> Bool
forall a. Instruction a -> Bool
isArg DockerfilePart
afterFirstFroms

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

isArg :: Docker.Instruction a -> Bool
isArg :: Instruction a -> Bool
isArg (Docker.Arg Text
_ Maybe Text
_) = Bool
True
isArg Instruction a
_ = Bool
False