import Pf.Crafting
import Test.QuickCheck
import Test.Hspec

main :: IO ()
main = hspec $ do
  describe "Crafting" $ do
    it "should result in success if the roll is greater than the craft dc of the item." $
      property craftingSuccessGreater
    it "should result in success if the roll is equal to the craft dc of the item." $
      property craftingSuccessEqual
    it "should result in failure if the roll is less than the dc of the item bt not by more than 4." $
      property craftingFailure
    it "should result in failure by five if the roll is less than the dc of the item by five or more." $
      property craftingFailureByFive
    it "should result in completion if progress is greater than the required progress." $
      property craftingCompletedItemGreater
    it "should result in completion if progress is equal to the required progress." $
      property craftingCompletedItemEqual
  describe "Duration" $ do
    it "should result in 1/7th the duration when the duration is Day" $
      property craftingDurationDay

craftingSuccessGreater :: CraftProgress -> Roll -> CraftDuration -> Bool
craftingSuccessGreater cp (Roll r) d =
  let x = dc (item cp)
  in craftCheck cp (Roll $ r + x) d == (CraftSuccess $ increaseProgress cp (Roll $ r + x) d)

craftingSuccessEqual :: CraftProgress -> CraftDuration -> Bool
craftingSuccessEqual cp d =
  let x = dc $ item cp
  in craftCheck cp (Roll x) d == (CraftSuccess $ increaseProgress cp (Roll x) d)

craftingFailure :: CraftProgress -> CraftDuration -> Bool
craftingFailure cp d = craftCheck cp (Roll $ dc (item cp) - 4) d == CraftFailure cp

craftingFailureByFive :: CraftProgress -> CraftDuration -> Bool
craftingFailureByFive cp d = craftCheck cp (Roll $ dc (item cp) - 5) d == CraftFailureByFiveOrMore cp

craftingCompletedItemGreater :: CraftProgress -> Roll -> CraftDuration -> Bool
craftingCompletedItemGreater p x d =
  let CraftProgress i r (Progress a) (Progress b) = p
      prog = CraftProgress i r (Progress $ a + b) (Progress b)
  in craft (Just prog) i x d ==  CraftCompleted prog

craftingCompletedItemEqual :: CraftProgress -> Roll -> CraftDuration -> Bool
craftingCompletedItemEqual p x d =
  let (CraftProgress i r _ b) = p
      prog = CraftProgress i r b b
  in craft (Just prog) i x d == CraftCompleted prog

craftingDurationDay :: CraftProgress -> Roll -> Bool
craftingDurationDay (CraftProgress i r (Progress a) b) (Roll x) =
  let prog = CraftProgress i r (Progress a) b
  in increaseProgress prog (Roll x) Day == prog { progress = Progress $ ((x * dc i) `div` 7) + a }
