{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module      : Data.Git.Named
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : unix
--
module Data.Git.Named
	( headList
	, headExists
	, headRead
	, headWrite
	, remotesList
	, remoteList
	, tagList
	, tagExists
	, tagRead
	, tagWrite
	, specialRead
	, specialExists
	) where

import Control.Applicative ((<$>))

import System.Directory

import Data.Git.Path
import Data.Git.Ref
import Data.List (isPrefixOf)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC

getDirectoryContentNoDots path = filter noDot <$> getDirectoryContents path
	where noDot = (not . isPrefixOf ".")

headList gitRepo = getDirectoryContentNoDots (headsPath gitRepo)
tagList gitRepo = getDirectoryContentNoDots (tagsPath gitRepo)
remotesList gitRepo = getDirectoryContentNoDots (remotesPath gitRepo)
remoteList gitRepo remote = getDirectoryContentNoDots (remotePath gitRepo remote)

writeRef path ref = B.writeFile path (B.concat [toHex ref, B.singleton 0xa])
readRef path = fromHex . B.take 40 <$> B.readFile path

readRefAndFollow gitRepo path = do
	content <- B.readFile path
	if "ref: " `B.isPrefixOf` content
		then do -- BC.unpack should be utf8.toString, and the whole thing is really fragile. need to do the proper thing.
			let file = BC.unpack $ BC.init $ B.drop 5 content
			readRefAndFollow gitRepo (gitRepo ++ "/" ++ file)
		else return (fromHex $ B.take 40 content)

headExists gitRepo name    = doesFileExist (headPath gitRepo name)
headRead gitRepo name      = readRef (headPath gitRepo name)
headWrite gitRepo name ref = writeRef (headPath gitRepo name) ref

tagExists gitRepo name    = doesFileExist (tagPath gitRepo name)
tagRead gitRepo name      = readRef (tagPath gitRepo name)
tagWrite gitRepo name ref = writeRef (tagPath gitRepo name) ref

specialRead gitRepo name   = readRefAndFollow gitRepo (specialPath gitRepo name)
specialExists gitRepo name = doesFileExist (specialPath gitRepo name)