{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}

module HsDev.Tools.Refact (
        Refact(..), refactMessage, refactAction,
        refact, update,

        replace, cut, paste,

        fromRegion, fromPosition
        ) where

import Control.Lens hiding ((.=))
import Data.Aeson
import Data.Text (Text)
import Data.Text.Region hiding (Region(..), update)
import qualified Data.Text.Region as R

import HsDev.Symbols.Location
import HsDev.Util

data Refact = Refact {
        _refactMessage :: Text,
        _refactAction :: Replace Text }
                deriving (Eq, Show)

instance ToJSON Refact where
        toJSON (Refact msg cor) = object [
                "message" .= msg,
                "action" .= cor]

instance FromJSON Refact where
        parseJSON = withObject "correction" $ \v -> Refact <$>
                v .:: "message" <*>
                v .:: "action"

makeLenses ''Refact

instance Regioned Refact where
        regions = refactAction . regions

refact :: [Refact] -> Text -> Text
refact rs = apply act where
        act = Edit (rs ^.. each . refactAction)

update :: Regioned a => [Refact] -> [a] -> [a]
update rs = map (R.update act) where
        act = Edit (rs ^.. each . refactAction)

fromRegion :: Region -> R.Region
fromRegion (Region f t) = fromPosition f `till` fromPosition t

fromPosition :: Position -> Point
fromPosition (Position l c) = pt (pred l) (pred c)