{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
module Darcs.Patch.V1.Core
    ( RepoPatchV1(..),
      isMerger, mergerUndo
    ) where

import Prelude ()
import Darcs.Prelude

import Darcs.Patch.Format
    ( PatchListFormat(..)
    , ListFormat(ListFormatV1)
    )
import Darcs.Patch.Debug ( PatchDebug(..) )
import Darcs.Patch.Prim
    ( FromPrim(..), PrimPatchBase(..), PrimPatch
    )
import Darcs.Patch.Repair ( Check )

import Darcs.Patch.Witnesses.Ordered ( FL(..), RL )
import Darcs.Patch.Witnesses.Show
    ( Show1(..), Show2(..)
    , ShowDict(ShowDictClass)
    , appPrec, showsPrec2
    )

-- This haddock could be put on the individual bits of Merger instead
-- once haddock supports doc comments on GADT constructors
{- |
The format of a merger is @Merger undos unwindings conflicting original@.

@undos@ = the effect of the merger

@unwindings@ = TODO: eh?

@conflicting@ = the patch we conflict with

@original@ = the patch we really are
-}
data RepoPatchV1 prim wX wY where
    PP :: prim wX wY -> RepoPatchV1 prim wX wY
    Merger :: FL (RepoPatchV1 prim) wX wY
           -> RL (RepoPatchV1 prim) wX wB
           -> RepoPatchV1 prim wC wB
           -> RepoPatchV1 prim wC wD
           -> RepoPatchV1 prim wX wY
    Regrem :: FL (RepoPatchV1 prim) wX wY
           -> RL (RepoPatchV1 prim) wX wB
           -> RepoPatchV1 prim wC wB
           -> RepoPatchV1 prim wC wA
           -> RepoPatchV1 prim wY wX

instance Show2 prim => Show (RepoPatchV1 prim wX wY)  where
    showsPrec :: Int -> RepoPatchV1 prim wX wY -> ShowS
showsPrec d :: Int
d (PP p :: prim wX wY
p) =
        Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String -> ShowS
showString "PP " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> prim wX wY -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) prim wX wY
p
    showsPrec d :: Int
d (Merger undos :: FL (RepoPatchV1 prim) wX wY
undos unwindings :: RL (RepoPatchV1 prim) wX wB
unwindings conflicting :: RepoPatchV1 prim wC wB
conflicting original :: RepoPatchV1 prim wC wD
original) =
        Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
            String -> ShowS
showString "Merger " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> FL (RepoPatchV1 prim) wX wY -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) FL (RepoPatchV1 prim) wX wY
undos ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            String -> ShowS
showString " " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> RL (RepoPatchV1 prim) wX wB -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) RL (RepoPatchV1 prim) wX wB
unwindings ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            String -> ShowS
showString " " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> RepoPatchV1 prim wC wB -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) RepoPatchV1 prim wC wB
conflicting ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            String -> ShowS
showString " " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> RepoPatchV1 prim wC wD -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) RepoPatchV1 prim wC wD
original
    showsPrec d :: Int
d (Regrem undos :: FL (RepoPatchV1 prim) wY wX
undos unwindings :: RL (RepoPatchV1 prim) wY wB
unwindings conflicting :: RepoPatchV1 prim wC wB
conflicting original :: RepoPatchV1 prim wC wA
original) =
        Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
            String -> ShowS
showString "Regrem " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> FL (RepoPatchV1 prim) wY wX -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) FL (RepoPatchV1 prim) wY wX
undos ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            String -> ShowS
showString " " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> RL (RepoPatchV1 prim) wY wB -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) RL (RepoPatchV1 prim) wY wB
unwindings ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            String -> ShowS
showString " " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> RepoPatchV1 prim wC wB -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) RepoPatchV1 prim wC wB
conflicting ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            String -> ShowS
showString " " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> RepoPatchV1 prim wC wA -> ShowS
forall (a :: * -> * -> *) wX wY. Show2 a => Int -> a wX wY -> ShowS
showsPrec2 (Int
appPrec Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) RepoPatchV1 prim wC wA
original

instance Show2 prim => Show1 (RepoPatchV1 prim wX) where
    showDict1 :: ShowDict (RepoPatchV1 prim wX wX)
showDict1 = ShowDict (RepoPatchV1 prim wX wX)
forall a. Show a => ShowDict a
ShowDictClass

instance Show2 prim => Show2 (RepoPatchV1 prim) where
    showDict2 :: ShowDict (RepoPatchV1 prim wX wY)
showDict2 = ShowDict (RepoPatchV1 prim wX wY)
forall a. Show a => ShowDict a
ShowDictClass

instance PrimPatch prim => PrimPatchBase (RepoPatchV1 prim) where
    type PrimOf (RepoPatchV1 prim) = prim

instance FromPrim (RepoPatchV1 prim) where
    fromPrim :: PrimOf (RepoPatchV1 prim) wX wY -> RepoPatchV1 prim wX wY
fromPrim = PrimOf (RepoPatchV1 prim) wX wY -> RepoPatchV1 prim wX wY
forall (prim :: * -> * -> *) wX wY.
prim wX wY -> RepoPatchV1 prim wX wY
PP

isMerger :: RepoPatchV1 prim wA wB -> Bool
isMerger :: RepoPatchV1 prim wA wB -> Bool
isMerger (Merger{}) = Bool
True
isMerger (Regrem{}) = Bool
True
isMerger _ = Bool
False

mergerUndo :: RepoPatchV1 prim wX wY -> FL (RepoPatchV1 prim) wX wY
mergerUndo :: RepoPatchV1 prim wX wY -> FL (RepoPatchV1 prim) wX wY
mergerUndo (Merger undo :: FL (RepoPatchV1 prim) wX wY
undo _ _ _) = FL (RepoPatchV1 prim) wX wY
undo
mergerUndo _ = FL (RepoPatchV1 prim) wX wY
forall a. a
impossible

instance PatchListFormat (RepoPatchV1 prim) where
   -- In principle we could use ListFormatDefault when prim /= V1 Prim patches,
   -- as those are the only case where we need to support a legacy on-disk
   -- format. In practice we don't expect Patch to be used with any other argument
   -- anyway, so it doesn't matter.
   patchListFormat :: ListFormat (RepoPatchV1 prim)
patchListFormat = ListFormat (RepoPatchV1 prim)
forall (p :: * -> * -> *). ListFormat p
ListFormatV1

instance Check (RepoPatchV1 prim)
   -- no checks

instance PatchDebug prim => PatchDebug (RepoPatchV1 prim)