-- | Generate random Haskell syntax entities. This package was used by
-- @lens@ in versions not released to Hackage.
module Language.Valid.Random (
  randomSymbol, randomSymbolIO,
  randomModule, randomModuleIO
) where

import Control.Monad
import Control.Monad.Random
import Data.Set (elemAt, size, Set)
import Language.Valid.Private

randomSetMember :: RandomGen g => Set a -> Rand g a
randomSetMember s = do
    r <- getRandomR (0 :: Int, size s - 1)
    return $ elemAt r s

randomSymbolR :: RandomGen g => Rand g String
randomSymbolR = do
    len <- getRandomR (1 :: Int, 8)
    replicateM len (randomSetMember symbolChars)

randomModuleR :: RandomGen g => Rand g String
randomModuleR = do
    len <- getRandomR (0 :: Int, 15)
    s <- randomSetMember moduleStartChars
    ns <- replicateM len (randomSetMember moduleChars)
    return $ s:ns

-- | Produce a random symbol of length 1-8 in IO.
randomSymbolIO :: IO String
randomSymbolIO = evalRandIO randomSymbolR

-- | Produce a random module name of length 1-16 in IO.
randomModuleIO :: IO String
randomModuleIO = evalRandIO randomModuleR

-- | Produce a random symbol of length 1-8.
randomSymbol :: RandomGen g => g -> (String, g)
randomSymbol = runRand randomSymbolR

-- | Produce a random module name of length 1-16.
randomModule :: RandomGen g => g -> (String, g)
randomModule = runRand randomModuleR