{-# LANGUAGE DefaultSignatures, OverloadedStrings #-}

module HsDev.Symbols.Documented (
	Documented(..),
	defaultDetailed
	) where

import Control.Lens (view, (^..), (^?))
import Data.Maybe (maybeToList)
import Data.Text (Text, pack)
import qualified Data.Text as T

import Text.Format
import HsDev.Symbols.Class
import HsDev.Project.Types

-- | Documented symbol
class Documented a where
	brief :: a -> Text
	detailed :: a -> Text
	default detailed :: Sourced a => a -> Text
	detailed = T.unlines . defaultDetailed

-- | Default detailed docs
defaultDetailed :: (Sourced a, Documented a) => a -> [Text]
defaultDetailed s = concat [header, docs, loc] where
	header = [brief s, ""]
	docs = s ^.. sourcedDocs
	loc = maybe [] (\l -> ["Defined at " `T.append` pack (show l)]) (s ^? sourcedLocation)

instance Documented ModulePackage where
	brief = pack . show
	detailed = brief

instance Documented ModuleLocation where
	brief (FileModule f _) = f
	brief (InstalledModule _ pkg n _) = format "{} from {}" ~~ n ~~ brief pkg
	brief (OtherLocation src) = src
	brief NoLocation = "<no-location>"
	detailed (FileModule f mproj) = case mproj of
		Nothing -> f
		Just proj -> format "{} in project {}" ~~ f ~~ brief proj
	detailed (InstalledModule pdb pkg n _) = format "{} from {} ({})" ~~ n ~~ brief pkg ~~ show pdb
	detailed l = brief l

instance Documented Project where
	brief p = format "{} ({})" ~~ view projectName p ~~ view projectPath p
	detailed p = T.unlines (brief p : desc) where
		desc = concat [
			do
				d <- mdescr
				_ <- maybeToList $ view projectLibrary d
				return "\tlibrary",
			do
				d <- mdescr
				exe <- view projectExecutables d
				return $ format "\texecutable: {}" ~~ view executableName exe,
			do
				d <- mdescr
				test <- view projectTests d
				return $ format "\ttest: {}" ~~ view testName test]
		mdescr = maybeToList $ view projectDescription p