--
-- Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
--
-- SPDX-License-Identifier: BSD-2-Clause
--

module CapDL.DumpParser where

import CapDL.AST
import CapDL.Model
import CapDL.ParserUtils

import Text.ParserCombinators.Parsec

import Prelude ()
import Prelude.Compat
import Control.Monad (when)
import qualified Data.Set as Set
import qualified Data.Map as Map
import Data.List.Compat
import Data.List.Split
import Data.Ord
import Numeric
import Data.Maybe

--Assumes that untypeds come before anything with an address

insertCov :: ObjID -> ObjID -> MapParser ()
insertCov cov untyp = do
    maps <- getState
    let covM = covMap maps
        covSet = Map.findWithDefault Set.empty untyp covM
        covSet' = Set.insert cov covSet
    setState $ maps { covMap = Map.insert untyp covSet' covM }

getCovs :: MapParser [(ObjID, Set.Set ObjID)]
getCovs = do
    maps <- getState
    return $ Map.toList $ covMap maps

insertAddrs :: (Word, Word) -> ObjID -> MapParser ()
insertAddrs addrs objID = do
    maps <- getState
    let addrM = addrMap maps
    setState $ maps { addrMap = Map.insert objID addrs addrM }

included :: Word -> (Word, Word) -> Bool
included n (st, end) = n >= st && n < end

getUntypSize :: String -> Int
getUntypSize string = read $ splitOn "@" string !! 2

lookupAddr :: Word -> MapParser (Maybe ObjID)
lookupAddr addr = do
    maps <- getState
    let ids = map fst $ filter (included addr . snd) $ Map.toList $ addrMap maps
        id = minimumBy (comparing (getUntypSize . fst)) ids
    return $ case ids of
                 [] -> Nothing
                 _ -> Just id

insertRef :: Name -> ObjID -> MapParser ()
insertRef dumpID objID = do
    maps <- getState
    let refM = refMap maps
    setState $ maps { refMap = Map.insert dumpID objID refM }

lookupRef :: Name -> MapParser ObjID
lookupRef dumpID = do
    maps <- getState
    let id = Map.lookup dumpID $ refMap maps
    case id of
        Just id -> return id
        Nothing -> return (dumpID, Nothing)

getAddr :: String -> Maybe Word
getAddr string =
    if '@' `elem` string
    then Just $ fst.head.readHex $ splitOn "@0x" string !! 1
    else Nothing

getObjTyp :: String -> Maybe String
getObjTyp string =
    if '@' `elem` string
    then Just $ splitOn "@" string !! 0
    else Nothing

maybeInsertIRQ :: Name -> MapParser ()
maybeInsertIRQ obj =
    when (getObjTyp obj == Just "irqhandler") $ do
        maps <- getState
        let irqM = irqMap maps
            slot = fromJust $ getAddr obj
        setState $ maps { irqMap = Map.insert slot obj irqM }

object :: MapParser KO
object = do
    typ <- object_type
    params <- object_params
    return (Obj typ params [])

maybe_object :: MapParser (Maybe (Name, KO))
maybe_object =
        do name <- name
           _ <- symbol "="
           obj <- CapDL.DumpParser.object
           return $ Just (name, obj)
    <|> return Nothing

sizeOf :: Arch -> KO -> Word
sizeOf _ (Obj Frame_T [VMSize vmSz] _) = vmSz
sizeOf _ (Obj Untyped_T [BitSize bSz] _) = 2 ^ bSz
sizeOf _ (Obj CNode_T [BitSize bSz] _) = 16 * 2 ^ bSz
sizeOf _ (Obj IrqSlot_T _ _) = 1
sizeOf _ (Obj Endpoint_T _ _) = 16
sizeOf _ (Obj Notification_T _ _) = 16
sizeOf _ (Obj ASIDPool_T _ _) = 4 * 2^10
sizeOf _ (Obj IOPT_T _ _) = 4 * 2^10
sizeOf _ (Obj IODevice_T _ _) = 1
sizeOf _ (Obj ARMIODevice_T _ _) = 1
sizeOf IA32 (Obj TCB_T _ _) = 2^10
sizeOf IA32 (Obj PD_T _ _) = 4 * 2^10
sizeOf IA32 (Obj PT_T _ _) = 4 * 2^10
sizeOf ARM11 (Obj TCB_T _ _) = 512
sizeOf ARM11 (Obj PD_T _ _) = 16 * 2^10
sizeOf ARM11 (Obj PT_T _ _) = 2^10
sizeOf _ _ = 0

consecutive :: Arch -> (Name, KO) -> Maybe (Name, KO) -> Word -> Bool
consecutive _ _ Nothing _ = False
consecutive arch (name1, obj1) (Just (name2, obj2)) num =
    let addr1 = getAddr name1
        addr2 = getAddr name2
    in case (addr1, addr2) of
        (Just addr1, Just addr2) ->
            obj1 == obj2 && addr1 + num * sizeOf arch obj1 == addr2
        _ -> False

considerUntypeds :: Arch -> ObjID -> Maybe Word -> KO -> MapParser ()
considerUntypeds arch refr addr obj =
    case (addr, obj) of
        (Just addr, Obj Untyped_T _ _ ) -> do
                                    covUn <- lookupAddr addr
                                    insertAddrs (addr, addr + sizeOf arch obj - 1) refr
                                    case covUn of
                                        Just covUn -> insertCov refr covUn
                                        Nothing -> return ()
        (Just addr, _) -> do covUn <- lookupAddr addr
                             case covUn of
                                Just covUn -> insertCov refr covUn
                                Nothing -> return ()
        (Nothing, _) -> return ()

maybe_obj_decl :: Arch -> (Name, KO) -> Word -> MapParser Word
maybe_obj_decl arch pre num = do
        next <- lookAhead maybe_object
        if consecutive arch pre next num
         then do let (name, obj) = fromJust next
                     refr = (fst pre, Just num)
                     addr = getAddr name
                 _ <- maybe_object
                 maybeInsertIRQ name
                 insertRef name refr
                 considerUntypeds arch refr addr obj
                 total <- maybe_obj_decl arch pre (num + 1)
                 return total
         else return num

obj_decl :: Arch -> MapParser KODecl
obj_decl arch = do
    name <- name
    _ <- symbol "="
    obj <- CapDL.DumpParser.object
    total <- maybe_obj_decl arch (name, obj) 1
    let (decl, refr) = if total == 1
                       then ((name, []), (name, Nothing))
                       else ((name, [Only total]), (name, Just 0))
        addr = getAddr name
    maybeInsertIRQ name
    insertRef name refr
    considerUntypeds arch refr addr obj
    return (KODecl [decl] obj)

obj_decls :: Arch -> MapParser [Decl]
obj_decls arch = do
    reserved "objects"
    decls <- braces $ many (obj_decl arch)
    return $ map ObjDecl decls

id_to_ref :: ObjID -> NameRef
id_to_ref (name, Nothing) = (name, [])
id_to_ref (name, Just n) = (name, [Only n])

make_obj :: Set.Set ObjID -> KO
make_obj covs = Obj Untyped_T [] $ map (Right . id_to_ref) $ Set.toList covs

cov_decl :: (ObjID, Set.Set ObjID) -> KODecl
cov_decl (refr, covs) =
    let obj = make_obj covs
    in KODecl [id_to_ref refr] obj

cov_decls :: MapParser [Decl]
cov_decls = do
    covs <- getCovs
    return $ map (ObjDecl . cov_decl) covs

cap_mapping :: MapParser CapMapping
cap_mapping = do
    sl <- maybe_slot
    obj <- name
    (n,num) <- lookupRef obj
    let obj' = case num of
            Just num -> (n, [Only num])
            Nothing -> (n, [])
    params <- cap_params
    parent <- maybe_parent
    return $ CapMapping sl Nothing obj' params parent

refToNameRef :: ObjID -> NameRef
refToNameRef (id, num) =
    case num of
        Just num -> (id, [Only num])
        Nothing -> (id, [])

cap_decl :: MapParser Decl
cap_decl = do
    n <- name
    ref <- lookupRef n
    let n' = refToNameRef ref
    ms <- braces (sepEndBy cap_mapping opt_semi)
    return $ CapDecl n' ms

cap_decls :: MapParser [Decl]
cap_decls = do
    reserved "caps"
    braces $ many (try cap_decl)

make_irq_mapping :: (Word, Name) -> MapParser CapMapping
make_irq_mapping (slot, irq) = do
    ref <- lookupRef irq
    let irq' = refToNameRef ref
    return $ IRQMapping (Just slot) irq'

make_irq_decl :: MapParser [Decl]
make_irq_decl = do
    maps <- getState
    let irqs = Map.toList $ irqMap maps
    irq_decls <- mapM make_irq_mapping irqs
    return [IRQDecl irq_decls]

all_decls :: Arch -> MapParser [Decl]
all_decls arch = do
    objs <- obj_decls arch
    cov <- cov_decls
    caps <- cap_decls
    cdt <- cdt_decls
    irq <- make_irq_decl
    return $ objs ++ cov ++ caps ++ cdt ++ irq

capDLDumpModule :: MapParser Module
capDLDumpModule = do
    whiteSpace
    arch <- parse_arch
    decls <- all_decls arch
    eof
    return (Module arch decls)
