-- main function for using single-threaded arrays
-- providing a baseline for performance

import System.Environment (getArgs)
import Control.Concurrent
import Control.Exception (finally)
import Control.Concurrent.STM
import Data.Array.MArray

import Base
import Cluster
import ContigEnds

main :: IO ()
main = do
  [ts,bam] <- getArgs -- use a single bam file
  timestamp "start"  
  (n,ls,rs) <- collect_links bam  
  timestamp "links collected"  
  as <- initializeSTM n
  timestamp "initialized"  
  let targets = genLists (read ts) n
  forkAndWait [mapM_ (atomically . scaffold1 rs ls as) x | x <- targets]
  timestamp "scaffolded"
  printSTM (snd as)
  timestamp "done!"

-- | Generate target lists as subsets of 0..n-1
genLists size total = [filter (<total) [n*size..(n+1)*size-1] | n <- [0..(total-1) `div` size]]

-- | Spawn a set of threads and wait for them to complete.
forkAndWait :: [IO ()] -> IO ()
forkAndWait actions = mapM myForkIO actions >>= mapM_ takeMVar
  where
    myForkIO :: IO () -> IO (MVar ())
    myForkIO io = do
      mvar <- newEmptyMVar
      forkIO (io `finally` putMVar mvar ())
      return mvar
