createProjectConfig :: ProjectRoot -> IO Text
createProjectConfig root = do
    scm <- detectVersionControl root
    putJustStrLn scm $ \tool ->
        "  ... detected " <> show tool <> " as a SCM"

    buildTool <- detectBuildTool root
    putJustStrLn buildTool $ \tool ->
        "  ... detected " <> show tool <> " as a build tool."

    pure $ Text.unlines
        [ "# Source Code Management (SCM) tool used by the project."
        , "# Currently only 'Git' is recognized automatically."
        , field' "scm" $ Scm.toText <$> scm
        , ""
        , "# Build tool used by the project."
        , "# Currently only 'Cabal' and 'Stack' are recognized automatically."
        , field' "build-tool" $ BuildTool.toText <$> buildTool
        , ""
        , "# Settings in global section are always applied, regardless of\
            \ environment is"
        , "# used."
        , "global:"
        , "  env:"
        , "    # User can override these variables in \"${HOME}/.bash_yx\",\
            \ that is usually"
        , "    # necessary on systems with different installation paths for\
            \ these tools."
        , "    #YX_STACK_EXE: /usr/bin/stack"
        , "    #YX_GIT_EXE: /usr/bin/git"
        , ""
        , "  bin:"
        , ""
        , "# Environments for this project."
        , "environment:"
        , "  # Execution environment named \"default\". It is used when there\
            \ is no"
        , "  # environment specified on the command line, due to \"is-default:\
            \ true\"."
        , "  default:"
        , "    is-default: true"
        , ""
        , "    # Add or modify environment variables of the isolated execution"
        , "    # environment."
        , "    env:"
        , "    #  PATH: \"/some/path/bin:${PATH}\""
        , ""
        , "    # Add following commands/executables in to the isolated execution"
        , "    # environment."
        , "    #"
        , "    # When creating symlink, the command has always have to be\
            \ absolute path to"
        , "    # the executable."
        , "    bin:"
        , "      #stack:"
        , "      #  type: command"
        , "      #  command: stack build"
        , "      #  env:"
        , "      #    STACK_YAML: ${YX_PROJECT_ROOT}/stack-production.yaml"
        , "      #"
        , "      #alex:"
        , "      #  type: symlink"
        , "      #  command: /opt/alex/3.1.7/bin/alex"
        , "      #"
        , "      #happy:"
        , "      #  type: symlink"
        , "      #  command: /opt/happy/1.19.5/bin/happy"
        , "      #"
        , "      #build:"
        , "      #  type: alias"
        , "      #  command: ${YX_ENVIRONMENT_DIR}/bin/stack build"
        , "      #"
        , "      #hoogle:"
        , "      #  type: alias"
        , "      #  command: \"stack exec hoogle --\""
        ]
  where
    field :: Text -> Text -> Text
    field name value = name <> ": \"" <> value <> "\""

    field' :: Text -> Maybe Text -> Text
    field' name = \case
        Nothing -> "#" <> name <> ":"
        Just value -> field name value

-- | Detect if project contains YX project configuration file, and which, if
-- its found.
createProjectConfig :: ProjectRoot -> IO Text
createProjectConfig root = do
    scm <- detectVersionControl root
    putJustStrLn scm $ \tool ->
        "  ... detected " <> show tool <> " as a SCM"

    buildTool <- detectBuildTool root
    putJustStrLn buildTool $ \tool ->
        "  ... detected " <> show tool <> " as a build tool."

    pure $ Text.unlines
        [ "# Source Code Management (SCM) tool used by the project."
        , "# Currently only 'Git' is recognized automatically."
        , field' "scm" $ Scm.toText <$> scm
        , ""
        , "# Build tool used by the project."
        , "# Currently only 'Cabal' and 'Stack' are recognized automatically."
        , field' "build-tool" $ BuildTool.toText <$> buildTool
        , ""
        , "# Settings in global section are always applied, regardless of\
            \ environment is"
        , "# used."
        , "global:"
        , "  env:"
        , "    # User can override these variables in \"${HOME}/.bash_yx\",\
            \ that is usually"
        , "    # necessary on systems with different installation paths for\
            \ these tools."
        , "    #YX_STACK_EXE: /usr/bin/stack"
        , "    #YX_GIT_EXE: /usr/bin/git"
        , ""
        , "  bin:"
        , ""
        , "# Environments for this project."
        , "environment:"
        , "  # Execution environment named \"default\". It is used when there\
            \ is no"
        , "  # environment specified on the command line, due to \"is-default:\
            \ true\"."
        , "  default:"
        , "    is-default: true"
        , ""
        , "    # Add or modify environment variables of the isolated execution"
        , "    # environment."
        , "    env:"
        , "    #  PATH: \"/some/path/bin:${PATH}\""
        , ""
        , "    # Add following commands/executables in to the isolated execution"
        , "    # environment."
        , "    #"
        , "    # When creating symlink, the command has always have to be\
            \ absolute path to"
        , "    # the executable."
        , "    bin:"
        , "      #stack:"
        , "      #  type: command"
        , "      #  command: stack build"
        , "      #  env:"
        , "      #    STACK_YAML: ${YX_PROJECT_ROOT}/stack-production.yaml"
        , "      #"
        , "      #alex:"
        , "      #  type: symlink"
        , "      #  command: /opt/alex/3.1.7/bin/alex"
        , "      #"
        , "      #happy:"
        , "      #  type: symlink"
        , "      #  command: /opt/happy/1.19.5/bin/happy"
        , "      #"
        , "      #build:"
        , "      #  type: alias"
        , "      #  command: ${YX_ENVIRONMENT_DIR}/bin/stack build"
        , "      #"
        , "      #hoogle:"
        , "      #  type: alias"
        , "      #  command: \"stack exec hoogle --\""
        ]
  where
    field :: Text -> Text -> Text
    field name value = name <> ": \"" <> value <> "\""

    field' :: Text -> Maybe Text -> Text
    field' name = \case
        Nothing -> "#" <> name <> ":"
        Just value -> field name value

-- | Detect if project contains YX project configuration file, and which, if
-- its found.
createProjectConfig root = do
    scm <- detectVersionControl root
    putJustStrLn scm $ \tool ->
        "  ... detected " <> show tool <> " as a SCM"

    buildTool <- detectBuildTool root
    putJustStrLn buildTool $ \tool ->
        "  ... detected " <> show tool <> " as a build tool."

    pure $ Text.unlines
        [ "# Source Code Management (SCM) tool used by the project."
        , "# Currently only 'Git' is recognized automatically."
        , field' "scm" $ Scm.toText <$> scm
        , ""
        , "# Build tool used by the project."
        , "# Currently only 'Cabal' and 'Stack' are recognized automatically."
        , field' "build-tool" $ BuildTool.toText <$> buildTool
        , ""
        , "# Settings in global section are always applied, regardless of\
            \ environment is"
        , "# used."
        , "global:"
        , "  env:"
        , "    # User can override these variables in \"${HOME}/.bash_yx\",\
            \ that is usually"
        , "    # necessary on systems with different installation paths for\
            \ these tools."
        , "    #YX_STACK_EXE: /usr/bin/stack"
        , "    #YX_GIT_EXE: /usr/bin/git"
        , ""
        , "  bin:"
        , ""
        , "# Environments for this project."
        , "environment:"
        , "  # Execution environment named \"default\". It is used when there\
            \ is no"
        , "  # environment specified on the command line, due to \"is-default:\
            \ true\"."
        , "  default:"
        , "    is-default: true"
        , ""
        , "    # Add or modify environment variables of the isolated execution"
        , "    # environment."
        , "    env:"
        , "    #  PATH: \"/some/path/bin:${PATH}\""
        , ""
        , "    # Add following commands/executables in to the isolated execution"
        , "    # environment."
        , "    #"
        , "    # When creating symlink, the command has always have to be\
            \ absolute path to"
        , "    # the executable."
        , "    bin:"
        , "      #stack:"
        , "      #  type: command"
        , "      #  command: stack build"
        , "      #  env:"
        , "      #    STACK_YAML: ${YX_PROJECT_ROOT}/stack-production.yaml"
        , "      #"
        , "      #alex:"
        , "      #  type: symlink"
        , "      #  command: /opt/alex/3.1.7/bin/alex"
        , "      #"
        , "      #happy:"
        , "      #  type: symlink"
        , "      #  command: /opt/happy/1.19.5/bin/happy"
        , "      #"
        , "      #build:"
        , "      #  type: alias"
        , "      #  command: ${YX_ENVIRONMENT_DIR}/bin/stack build"
        , "      #"
        , "      #hoogle:"
        , "      #  type: alias"
        , "      #  command: \"stack exec hoogle --\""
        ]
  where
    field :: Text -> Text -> Text
    field name value = name <> ": \"" <> value <> "\""

    field' :: Text -> Maybe Text -> Text
    field' name = \case
        Nothing -> "#" <> name <> ":"
        Just value -> field name value

-- | Detect if project contains YX project configuration file, and which, if
-- its found.