module TesML.Data.Path (Path
                      , PathToken (..)
                      , PathStack
                      , rootPathStack
                      , pushPathStack)
where


import TesML.Data.Types


type Path = String


data PathToken = PathToken String Size
  deriving Show


type PathStack = [PathToken]


pathSeparator :: String
pathSeparator = "/"


rootPathStack :: PathStack
rootPathStack = [PathToken pathSeparator (maxBound :: Size)]


pushPathStack :: (String, Size, Size) -> PathStack -> Either String PathStack
pushPathStack (name, ownSz, fullSz) [] = Right $ (PathToken (pathSeparator ++ name ++ pathSeparator) (fullSz - ownSz)) : rootPathStack
pushPathStack tk@(name, ownSz, fullSz) stack@((PathToken parentPath parentSz) : _)
  | ownSz    > fullSz = Left $ "Trying to push invalid token to PathStack. OwnSize > FullSize. " ++ msgEnd
  | parentSz < ownSz  = Left $ "PathStack underrun. " ++ msgEnd
  | parentSz < fullSz = Left $ "PathStack will be underrun when processing children. Child entries need more\
                               \ space than parent has. " ++ msgEnd


  -- last child
  | parentSz == ownSz = Right filteredCutStack

  -- childless, has more siblings
  | parentSz > ownSz && ownSz == fullSz = Right cutStack

  -- has children
  | parentSz > ownSz && ownSz < fullSz = Right $ (PathToken (parentPath ++ name ++ pathSeparator) (fullSz - ownSz)) : cutStack

  | otherwise = Left $ "Unhandled case when pushing PathStack." ++ msgEnd

  where cutStack = fmap (\(PathToken p' s') -> PathToken p' (s' - ownSz)) stack
        filteredCutStack = filter (\(PathToken _ s') -> s' > 0) cutStack
        msgEnd = "Token " ++ show tk ++ ", pushing to: " ++ show stack




