content: {-# LANGUAGE ScopedTypeVariables #-}
  {-# LANGUAGE BangPatterns #-}
  -- BANNERSTART
  -- - Copyright 2006-2008, Galois, Inc.
  -- - This software is distributed under a standard, three-clause BSD license.
  -- - Please see the file LICENSE, distributed with this software, for specific
  -- - terms and conditions.
  -- Author: Adam Wick <awick@galois.com> and Magnus Carlsson <magnus@galois.com>
  -- BANNEREND
  import Communication.IVC
  import Control.Monad
  import Data.ByteString.Lazy(ByteString)
  import qualified Data.ByteString.Lazy as BS
  import Data.Time
  import Data.Word
  import Hypervisor.Console
  import Hypervisor.Debug
  import Hypervisor.XenStore
  import Numeric
  
  import Common
  
  main :: IO ()
  main = do
    xs <- initXenStore
    con <- initXenConsole
    args <- alistArgs
    let Just inName = lookup "inchan" args
    writeDebugConsole "END: Building input channel.\n"
    let (_, makeInChan) = connectionBuilders inName
    ichan <- makeInChan xs
    writeDebugConsole "END: Built input channel.\n"
    get ichan
    writeDebugConsole "END: Got first item.\n"
    start <- getCurrentTime
    writeDebugConsole "END: Got current time.\n"
    run_getter con 0 0 start ichan
  
  run_getter :: Console ->
                Word64 -> Word64 ->
                UTCTime -> InChannel ByteString ->
                IO ()
  run_getter con !total !x !start_t !c
    | x >= print_amt = do print_speed con start_t total
                          run_getter con total 0 start_t c
    | otherwise      = do block <- get c
  {-
                          unless (block == dataBlob) $ do
                            writeConsole con "Data read error\n"
                            findDifference con 0 (BS.unpack block) (BS.unpack dataBlob)
                            fail "Read wrong data!"
  -}
                          let !size = fromIntegral $ BS.length block
                          run_getter con (total + size) (x + size) start_t c
   where
    print_amt = 128 * 1024 * 1024
  
  print_speed :: Console -> UTCTime -> Word64 -> IO ()
  print_speed con start numBytes = do
    now <- getCurrentTime
    let !diff     = diffUTCTime now start
        !diff_rat = toRational diff :: Rational
        !diff_dbl = fromRational diff_rat :: Float
        !amnt_dbl = fromIntegral numBytes :: Float
    writeConsole con $ "Read " ++ show numBytes ++ " in " ++ (show diff)
    writeConsole con $ "   " ++ showSpeed (amnt_dbl / diff_dbl) ++ "\n"
   where
    showSpeed x 
      | x < onek  = show x ++ " bps"
      | x < onem  = show (x / onek) ++ " KBps"
      | x < oneg  = show (x / onem) ++ " MBps"
      | otherwise = show (x / oneg) ++ " GBps"
    onek = 1024
    onem = 1024 * 1024
    oneg = 1024 * 1024 * 1024
  
  {-
  findDifference :: Console -> Integer -> [Word8] -> [Word8] -> IO ()
  findDifference con _ [] [] = writeConsole con "Same blocks?!\n"
  findDifference con _ [] _  = writeConsole con "First block ended prematurely\n"
  findDifference con _ _  [] = writeConsole con "Secnd block ended prematurely\n"
  findDifference con i (a:rest1) (b:rest2)
    | a == b    = findDifference con (i + 1) rest1 rest2
    | otherwise = writeConsole con ("Difference starts at byte " ++ show i ++
                                    " (" ++ show a ++ " /= " ++ show b ++ ")\n")
  -}
  