module Data.Attoparsec.Path (rootPath, relFilePath, absFilePath, relDirPath, absDirPath) where

import Data.Attoparsec.Text (Parser, char, takeWhile1)
import Data.Functor.Identity (Identity (..))
import qualified Data.Text as T
import Control.Applicative (Alternative (..))
import Path (Path, File, Dir, Abs, Rel, (</>))
import Unsafe.Coerce (unsafeCoerce)



rootPath :: Parser (Path Abs Dir)
rootPath =
  (unsafeCoerce . (:[])) <$> char '/'

chunkPath :: Parser (Path Rel File)
chunkPath =
  (unsafeCoerce . T.unpack) <$> takeWhile1 (/= '/')

relFilePath :: Parser (Path Rel File)
relFilePath =
  let parseComplex =
        (\head tail -> unsafeCoerce (unsafeCoerce head ++ unsafeCoerce tail))
          <$> chunkPath <*> absFilePath
      parseSimple = chunkPath
  in  parseComplex <|> parseSimple

absFilePath :: Parser (Path Abs File)
absFilePath =
  (</>) <$> rootPath <*> relFilePath

relDirPath :: Parser (Path Rel Dir)
relDirPath =
  (\files suffix -> unsafeCoerce (unsafeCoerce files ++ unsafeCoerce suffix))
    <$> relFilePath <*> rootPath

absDirPath :: Parser (Path Abs Dir)
absDirPath =
  (</>) <$> rootPath <*> relDirPath