module Data.Attoparsec.IP where

import Data.Attoparsec.Text (Parser, char, digit, hexadecimal)
import Data.Word (Word8, Word16)
import Control.Applicative ((<|>))
import Control.Monad (void)
import Net.Types (IPv4, IPv6)
import qualified Net.IPv4 as IPv4
import qualified Net.IPv6 as IPv6


ipv4 :: Parser IPv4
ipv4 = do
  a <- octet
  void $ char '.'
  b <- octet
  void $ char '.'
  c <- octet
  void $ char '.'
  d <- octet
  pure (IPv4.fromOctets a b c d)
  where
    octet :: Parser Word8
    octet = do
      (a,b,c) <-
        let oneDigit = do
              n <- digit
              pure ('0','0',n)
            twoDigit = do
              n <- digit
              m <- digit
              pure ('0',n,m)
            threeDigit = do
              n <- digit
              m <- digit
              o <- digit
              pure (n,m,o)
        in  threeDigit <|> twoDigit <|> oneDigit
      let n :: Word8
          n = read (a:b:c:[])
      pure n


ipv6 :: Parser IPv6
ipv6 = do
  a <- hexadecimal
  void $ char ':'
  b <- hexadecimal
  void $ char ':'
  c <- hexadecimal
  void $ char ':'
  d <- hexadecimal
  void $ char ':'
  (e,f,g,h) <- do
    let anotherColon = do
          void $ char ':'
          pure (0,0,0,0)
        moreChunks = do
          e' <- hexadecimal
          void $ char ':'
          f' <- hexadecimal
          void $ char ':'
          g' <- hexadecimal
          void $ char ':'
          h' <- hexadecimal
          pure (e',f',g',h')
    anotherColon <|> moreChunks
  pure (IPv6.fromWord16s a b c d e f g h)