-- | Apply the current environment and return a modified toolchain.
--
-- This function is experimental and subject to change!
--
-- Currently recognised environment variables are
--
--  [@CC@] Path to @C@ compiler.
--
--  [@LD@] Path to linker.
--
--  [@SHAKE_TOOLCHAIN_VARIANT@] One of the values of 'ToolChainVariant' (case insensitive). If this variable is not present, an attempt is made to determine the toolchain variant from the @C@ compiler command.
applyEnv :: ToolChain -> Action ToolChain
applyEnv toolChain = do
  cc <- getEnv "CC"
  ld <- getEnv "LD"
  vendor <- getEnv "SHAKE_TOOLCHAIN_VARIANT"
  return $ maybe id (set compilerCommand) cc
         $ maybe id (set linkerCommand) ld
         . maybe id (set variant) ((vendor >>= parseVendor) <|> (cc >>= vendorFromCommand))
         $ toolChain
  where
    parseVendor s =
      case map toLower s of
        "gcc" -> Just GCC
        "llvm" -> Just LLVM
        "clang" -> Just LLVM
        _ -> Nothing
    vendorFromCommand path =
      let x = takeFileName path
      in if "gcc" `isInfixOf` x || "g++" `isInfixOf` x
         then Just GCC
         else if "clang" `isInfixOf` x
         then Just LLVM
         else Just Generic

-- | Export a 'ToolChain' definition to a list of environment variable mappings, suitable e.g. for calling third-party configure scripts in cross-compilation mode.
--
-- Needs some fleshing out; currently only works for "standard" binutil toolchains.
applyEnv :: ToolChain -> Action ToolChain
applyEnv toolChain = do
  cc <- getEnv "CC"
  ld <- getEnv "LD"
  vendor <- getEnv "SHAKE_TOOLCHAIN_VARIANT"
  return $ maybe id (set compilerCommand) cc
         $ maybe id (set linkerCommand) ld
         . maybe id (set variant) ((vendor >>= parseVendor) <|> (cc >>= vendorFromCommand))
         $ toolChain
  where
    parseVendor s =
      case map toLower s of
        "gcc" -> Just GCC
        "llvm" -> Just LLVM
        "clang" -> Just LLVM
        _ -> Nothing
    vendorFromCommand path =
      let x = takeFileName path
      in if "gcc" `isInfixOf` x || "g++" `isInfixOf` x
         then Just GCC
         else if "clang" `isInfixOf` x
         then Just LLVM
         else Just Generic

-- | Export a 'ToolChain' definition to a list of environment variable mappings, suitable e.g. for calling third-party configure scripts in cross-compilation mode.
--
-- Needs some fleshing out; currently only works for "standard" binutil toolchains.
applyEnv toolChain = do
  cc <- getEnv "CC"
  ld <- getEnv "LD"
  vendor <- getEnv "SHAKE_TOOLCHAIN_VARIANT"
  return $ maybe id (set compilerCommand) cc
         $ maybe id (set linkerCommand) ld
         . maybe id (set variant) ((vendor >>= parseVendor) <|> (cc >>= vendorFromCommand))
         $ toolChain
  where
    parseVendor s =
      case map toLower s of
        "gcc" -> Just GCC
        "llvm" -> Just LLVM
        "clang" -> Just LLVM
        _ -> Nothing
    vendorFromCommand path =
      let x = takeFileName path
      in if "gcc" `isInfixOf` x || "g++" `isInfixOf` x
         then Just GCC
         else if "clang" `isInfixOf` x
         then Just LLVM
         else Just Generic

-- | Export a 'ToolChain' definition to a list of environment variable mappings, suitable e.g. for calling third-party configure scripts in cross-compilation mode.
--
-- Needs some fleshing out; currently only works for "standard" binutil toolchains.