module Maskbits(
  Maskbits(..) )
where

import Test.Tasty.QuickCheck ( Arbitrary(arbitrary), elements )


-- | A type representing the number of bits in a CIDR netmask.
data Maskbits =
    Zero
  | One
  | Two
  | Three
  | Four
  | Five
  | Six
  | Seven
  | Eight
  | Nine
  | Ten
  | Eleven
  | Twelve
  | Thirteen
  | Fourteen
  | Fifteen
  | Sixteen
  | Seventeen
  | Eighteen
  | Nineteen
  | Twenty
  | TwentyOne
  | TwentyTwo
  | TwentyThree
  | TwentyFour
  | TwentyFive
  | TwentySix
  | TwentySeven
  | TwentyEight
  | TwentyNine
  | Thirty
  | ThirtyOne
  | ThirtyTwo
    deriving (Enum, Eq, Ord)


instance Show Maskbits where
  show Zero        = "0"
  show One         = "1"
  show Two         = "2"
  show Three       = "3"
  show Four        = "4"
  show Five        = "5"
  show Six         = "6"
  show Seven       = "7"
  show Eight       = "8"
  show Nine        = "9"
  show Ten         = "10"
  show Eleven      = "11"
  show Twelve      = "12"
  show Thirteen    = "13"
  show Fourteen    = "14"
  show Fifteen     = "15"
  show Sixteen     = "16"
  show Seventeen   = "17"
  show Eighteen    = "18"
  show Nineteen    = "19"
  show Twenty      = "20"
  show TwentyOne   = "21"
  show TwentyTwo   = "22"
  show TwentyThree = "23"
  show TwentyFour  = "24"
  show TwentyFive  = "25"
  show TwentySix   = "26"
  show TwentySeven = "27"
  show TwentyEight = "28"
  show TwentyNine  = "29"
  show Thirty      = "30"
  show ThirtyOne   = "31"
  show ThirtyTwo   = "32"


instance Arbitrary Maskbits where
  arbitrary =
    elements [ Zero,
               One,
               Two,
               Three,
               Four,
               Five,
               Six,
               Seven,
               Eight,
               Nine,
               Ten,
               Eleven,
               Twelve,
               Thirteen,
               Fourteen,
               Fifteen,
               Sixteen,
               Seventeen,
               Eighteen,
               Nineteen,
               Twenty,
               TwentyOne,
               TwentyTwo,
               TwentyThree,
               TwentyFour,
               TwentyFive,
               TwentySix,
               TwentySeven,
               TwentyEight,
               TwentyNine,
               Thirty,
               ThirtyOne,
               ThirtyTwo ]


instance Read Maskbits where
  readsPrec _ s =
    case (reads s :: [(Int, String)]) of
      []              -> []
      (x,leftover):_  -> go x leftover
    where
      go :: Int -> String -> [(Maskbits, String)]
      go x' leftover'
        | x' < minBound || x' > maxBound = []
        | otherwise = [(toEnum x', leftover')]
