-- |
-- Module      : Minigent.Syntax.Utils.Row
-- Copyright   : (c) Data61 2018-2019
--                   Commonwealth Science and Research Organisation (CSIRO)
--                   ABN 41 687 119 230
-- License     : BSD3
--
-- A grab-bag of functions to manipulate rows, and to combine them and create them
-- in various ways.
--
-- It must be imported qualified to prevent prelude clashes.
{-# LANGUAGE FlexibleContexts #-}
module Minigent.Syntax.Utils.Row
  ( -- * Constructors
    fromList
  , incomplete
  , -- * Queries
    entries
  , entriesMap
  , rowTakenEntries
  , rowUntakenEntries
  , compatible
  , null
  , untakenTypes
  , typesFor
  , justVar
  , -- * Manipulating
    mapEntries
  , take
  , put
  , -- * Row Union and Combination
    -- ** Row Union
    union
  , UnionMethod
  , leastTaken
  , mostTaken
  , -- ** Common entries
    common
  , withoutCommon
  ) where


import Minigent.Syntax
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Minigent.Fresh as F
import Prelude hiding (take, null)
import Data.Maybe (mapMaybe)
import Control.Monad (guard)

-- | Given a list of entries, produce a complete row without a unification row variable.
fromList :: [Entry] -> Row
fromList es = Row (M.fromList (map (\e@(Entry f _ _ )-> (f,e)) es)) Nothing

-- | Given a list of entries, produce an incomplete row with a fresh unification row variable.
incomplete :: (Monad m, F.MonadFresh VarName m) => [Entry] -> m Row
incomplete es = do
  u <- F.fresh
  pure ((fromList es) { rowVar = Just u })

-- | Returns those pairs of entries in the input rows that have the same field/constructor
--   name.
common :: Row -> Row -> [(Entry, Entry)]
common r1 r2 = M.elems (M.intersectionWith (,) (rowEntries r1) (rowEntries r2))

-- | Returns whats left of the two input rows when all common entries are removed.
withoutCommon :: Row -> Row -> (Row, Row)
withoutCommon (Row e1 v1) (Row e2 v2) = ( Row (e1 `M.withoutKeys` M.keysSet e2) v1
                                        , Row (e2 `M.withoutKeys` M.keysSet e1) v2
                                        )

-- | Given a set of field names, return all the types for those field names in the row.
typesFor :: S.Set FieldName -> Row -> [Type]
typesFor fs (Row m _) = map (\(Entry _ t _ ) -> t) (M.elems (M.restrictKeys m fs))

-- | Does a row have no concrete entries and a unification variable, which is effectively an unconstrained unification variable
justVar :: Row -> Bool
justVar (Row es (Just _)) = M.null es
justVar _ = False

-- | Returns true iff the row has no entries and no unification variable.
null :: Row -> Bool
null (Row m Nothing) = M.null m
null _ = False

-- | Returns true iff the two rows could be considered equal after unification.
compatible :: Row -> Row -> Bool
compatible (Row m1 Nothing) (Row m2 Nothing) = M.keysSet m1 == M.keysSet m2
compatible (Row m1 Nothing) (Row m2 (Just _)) = M.keysSet m2 `S.isSubsetOf` M.keysSet m1
compatible (Row m1 (Just _)) (Row m2 Nothing) = M.keysSet m1 `S.isSubsetOf` M.keysSet m2
compatible (Row m1 (Just x)) (Row m2 (Just y)) = x /= y || M.keysSet m1 == M.keysSet m2


-- | Returns a list of all mappings marked as 'Taken' in the row.
rowTakenEntries :: Row -> M.Map FieldName Entry
rowTakenEntries = M.filter (\(Entry _ _ tk) -> tk) . rowEntries

-- | Returns all mappings not marked as 'Taken' in the row.
rowUntakenEntries :: Row -> M.Map FieldName Entry
rowUntakenEntries = M.filter (\(Entry _ _ tk) -> not tk) . rowEntries


-- | Returns all types not marked as 'Taken' in the row.
untakenTypes :: Row -> [Type]
untakenTypes = fmap (\(Entry _ t _) -> t) . M.elems . rowUntakenEntries

-- | Returns all known entries inside the row.
entries :: Row -> [Entry]
entries = M.elems . rowEntries

-- | Returns the row entries as a map from variable name to entry:
entriesMap :: Row -> M.Map VarName Entry
entriesMap = rowEntries

-- | Manipulate each entry inside a row. It is assumed that the given function
--   does not change the field or constructor name in the entry. Don't do that.
mapEntries :: (Entry -> Entry) -> Row -> Row
mapEntries func (Row m e) = Row (fmap func m) e

-- | Given a field name, mark is as taken in the row (if it exists).
take :: FieldName -> Row -> Row
take f (Row m e) = Row (M.adjust (\(Entry f t _) -> Entry f t True) f m) e

-- | Given a field name, unmark is as taken in the row (if it exists).
put :: FieldName -> Row -> Row
put f (Row m e) = Row (M.adjust (\(Entry f t _) -> Entry f t False) f m) e

-- | Returns true iff the field is taken in the given row.
takenIn :: FieldName -> Row -> Bool
takenIn f (Row m _) = case M.lookup f m of
   Nothing -> False
   Just (Entry _ _ b) -> b

-- | A @UnionMethod@ is a function that, given a particular field/constructor name,
--   and the two rows in which it may occur, decides whether or not this field should
--   be marked as taken or not.
type UnionMethod = (FieldName -> Row -> Row -> Taken)

-- | Given a @UnionMethod@ to determine if a field should be marked as taken or not,
--   combine two rows into a new one where each type is a fresh unification variable.
union :: (Monad m, F.MonadFresh VarName m) => UnionMethod -> Row -> Row -> m Row
union method r1@(Row m1 _) r2@(Row m2 _)= do
  let keys = S.toList (M.keysSet m1 `S.union` M.keysSet m2)
  entries <- mapM (\x -> Entry x . UnifVar <$> F.fresh <*> pure (method x r1 r2)) keys
  incomplete entries

-- | If the field or constructor is taken in all the rows in which it appears, then it
--   is taken in the union row.
leastTaken :: UnionMethod
leastTaken x r1@(Row m1 v1) r2@(Row m2 v2)
  | x `S.member` M.keysSet m1 && x `S.member` M.keysSet m2 = x `takenIn` r1 && x `takenIn` r2
  | x `S.member` M.keysSet m1 = x `takenIn` r1
  | x `S.member` M.keysSet m2 = x `takenIn` r2
  | otherwise                 = False

-- | If the field is taken in any of the rows in which it appears, then the field is taken
--   in the union row.
mostTaken :: UnionMethod
mostTaken x r1@(Row m1 v1) r2@(Row m2 v2)
  | x `S.member` M.keysSet m1 && x `S.member` M.keysSet m2 = x `takenIn` r1 || x `takenIn` r2
  | x `S.member` M.keysSet m1 = x `takenIn` r1
  | x `S.member` M.keysSet m2 = x `takenIn` r2
  | otherwise                 = True
