content: {-# LANGUAGE OverloadedStrings #-}
  
  module Hie.Yaml
    ( hieYaml,
      fmtComponent,
      fmtPkgs,
      cabalComponent,
      stackComponent,
    )
  where
  
  import qualified Data.Text as T
  import Hie.Cabal.Parser
  
  hieYaml :: String -> String -> String
  hieYaml sOrC pkgs =
    "cradle:\n"
      <> indent'
        (sOrC <> ":\n" <> indent' pkgs)
  
  indent' :: String -> String
  indent' =
    unlines
      . map
        ( \l -> case l of
            "" -> ""
            _ -> "  " <> l
        )
      . lines
  
  cabalComponent :: Name -> Component -> (FilePath, String)
  cabalComponent n (Comp Lib "" p) = (T.unpack p, T.unpack $ "lib:" <> n)
  cabalComponent n (Comp Lib cn p) = (T.unpack p, T.unpack $ n <> ":lib:" <> cn)
  cabalComponent n (Comp Exe cn p) = (T.unpack p, T.unpack $ n <> ":exe:" <> cn)
  cabalComponent n (Comp Bench cn p) = (T.unpack p, T.unpack $ n <> ":bench:" <> cn)
  cabalComponent n (Comp Test cn p) = (T.unpack p, T.unpack $ n <> ":test:" <> cn)
  
  stackComponent :: Name -> Component -> (FilePath, String)
  stackComponent n (Comp Lib "" p) = (T.unpack p, T.unpack $ n <> ":lib")
  stackComponent n (Comp Lib cn p) = (T.unpack p, T.unpack $ n <> ":lib:" <> cn)
  stackComponent n (Comp Exe cn p) = (T.unpack p, T.unpack $ n <> ":exe:" <> cn)
  stackComponent n (Comp Bench cn p) = (T.unpack p, T.unpack $ n <> ":bench:" <> cn)
  stackComponent n (Comp Test cn p) = (T.unpack p, T.unpack $ n <> ":test:" <> cn)
  
  fmtComponent :: (FilePath, String) -> String
  fmtComponent (p, c) =
    "- path: "
      <> dQuote p
      <> "\n  "
      <> "component: "
      <> dQuote c
  
  -- | Same as init but handle empty list without throwing errors.
  dropLast :: [a] -> [a]
  dropLast l = take (length l - 1) l
  
  fmtPkgs :: String -> [Package] -> String
  fmtPkgs sOrC pkgs = dropLast $ unlines l
    where
      comp = if sOrC == "cabal" then cabalComponent else stackComponent
      f (Package n cs) = map ((<> "\n") . fmtComponent . comp n) cs
      l = concatMap f pkgs
  
  dQuote :: String -> String
  dQuote t = '"' : t <> "\""
  