{-# LANGUAGE OverloadedStrings #-}

-- author: D.Mattei
-- installation summary:
-- instal Haskell platform (from web)
-- NOTE: you have now two cabal and ghci on the system ,use the good one !!!
-- in case: export PATH=/usr/local/bin:$PATH
-- install those modules with cabal:
--   /usr/local/bin/cabal update (if needed)
--   /usr/local/bin/cabal install HDBC
--   /usr/local/bin/cabal install HDBC-mysql
--   /usr/local/bin/cabal install mysql-simple (need to do it twice, check PATH and version for cabal?)
-- at this point you should get an error of ld.gold with mysqlclient library
-- solution is here: https://github.com/ryantm/hdbc-mysql/issues/20
--
-- editing Haskell: emacs
-- if haskell-mode is not available configure emacs to get and install it online reading the Quick Installation of the page:
-- https://github.com/haskell/haskell-mode
--
-- start the program like this:
-- $ ghci
-- GHCi, version 8.4.3: http://www.haskell.org/ghc/  :? for help
-- Prelude> :load UpdateSidonie
-- [1 of 1] Compiling Main             ( UpdateSidonie.hs, interpreted )
-- Ok, one module loaded.
-- *Main> main
-- [SqlInt64 2]x



import Database.MySQL.Simple
import Database.MySQL.Simple.QueryResults
import Database.MySQL.Simple.Result
import Control.Monad
--import Data.Text
import Data.Text as Text
--import Data.Int as Int
--import Data.List
import Debug.Trace

sqltreat :: String -> String -> String
sqltreat a b =  a ++ " " ++  b ++ " "


-- this function will return th N��BD from Sidonie for a given name
-- note: names have been standardized between Sidonie and WDS
getBD :: Connection -> String -> IO Float
getBD conn name = trace "Entering getBD" noBDfp
  where qry_head = "select `N�� BD` from Coordonn��es where Nom = ?" :: Query
        bd_rows :: IO [Only Text]
        bd_rows = query conn qry_head (Only (name::String))
--        noBDtxt :: [Text]
--        noBDtxt = fromOnly (Prelude.head bd_rows)
--        noBDtxt :: IO [Text]
        lg = fmap Prelude.length bd_rows
        lg2 = fmap show lg
        noBDtxt :: IO Text
--        noBDtxt = trace "lg " (fmap (fromOnly . Prelude.head) bd_rows)
        noBDtxt = (fmap (fromOnly . Prelude.head) bd_rows)
--        noBDstr :: String
--        noBDstr = Text.unpack noBDtxt
        noBDstr :: IO String
        noBDstr = fmap Text.unpack noBDtxt
--        noBDfp = read $ noBDstr :: Float
        noBDfp :: IO Float
        noBDfp = trace "Exiting getBD" (fmap read noBDstr)


-- this function will return the list of N��BD from WDS for a given name
-- note: there could be multiple result for a given name in WDS due to components
getBD_WDSb :: Connection -> String -> IO Float
getBD_WDSb conn name = trace "Entering getBD_WDS" noBDfp
  where qry_head = "select DNUM from WDS where DISC = ?" :: Query

        bd_rows :: IO [Only Text]
        bd_rows = query conn qry_head (Only (name::String))

        lg = fmap Prelude.length bd_rows

--        tst = if (fmap lg) > 1 then "some" else "one or zero" 

        noBDtxt :: IO Text
--        noBDtxt = trace "lg " (fmap (fromOnly . Prelude.head) bd_rows)
        noBDtxt = (fmap (fromOnly . Prelude.head) bd_rows)
--        noBDstr :: String
--        noBDstr = Text.unpack noBDtxt
        noBDstr :: IO String
        noBDstr = fmap Text.unpack noBDtxt
--        noBDfp = read $ noBDstr :: Float
        noBDfp :: IO Float
        noBDfp = trace "Exiting getBD" (fmap read noBDstr)


-- this function will return the list of N��BD from WDS for a given name
-- note: there could be multiple result for a given name in WDS due to components
getLstBD_WDS :: Connection -> String -> IO Int
getLstBD_WDS conn name = trace "Entering getLstBD_WDS" lg
  where qry_head = "select DNUM from WDS where DISC = ?" :: Query

        bd_rows :: IO [Only Text]
        bd_rows = query conn qry_head (Only (name::String))

        lg = fmap Prelude.length bd_rows

-- --        tst = if (fmap lg) > 1 then "some" else "one or zero" 

--         noBDtxt :: IO Text
-- --        noBDtxt = trace "lg " (fmap (fromOnly . Prelude.head) bd_rows)
--         noBDtxt = (fmap (fromOnly . Prelude.head) bd_rows)
-- --        noBDstr :: String
-- --        noBDstr = Text.unpack noBDtxt
--         noBDstr :: IO String
--         noBDstr = fmap Text.unpack noBDtxt
-- --        noBDfp = read $ noBDstr :: Float
--         noBDfp :: IO Float
--         noBDfp = trace "Exiting getBD" (fmap read noBDstr)


-- this function will return the list of N��BD from WDS for a given name
-- note: there could be multiple result for a given name in WDS due to components

getBD_WDSt :: Connection -> String -> IO Float
getBD_WDSt conn name = do
  let qry_head = "select DNUM from WDS where DISC = ?" :: Query

  bd_rows <- query conn qry_head (Only name)

  let lg = Prelude.length bd_rows

--  putStrLn (if lg > 1 then "some" else "one or zero")
  let tst = trace (if lg > 1 then "some" else "one or zero") (if lg > 1 then "some" else "one or zero")

--  let noBDtxt :: Text
  let noBDtxt = fromOnly (Prelude.head bd_rows)

  --        noBDstr :: String
  let noBDstr = Text.unpack noBDtxt

--        noBDfp :: Float
  let noBDfp = read noBDstr

  return noBDfp

-- getLstBD_WDS :: Connection -> String -> IO Int
-- getLstBD_WDS conn name = do
--   let qry_head = "select DNUM from WDS where DISC = ?" :: Query

--   bd_rows <- query conn qry_head (Only name)

--   let lg = Prelude.length bd_rows

--   return lg


action :: IO String
action = do
   putStrLn "This is a line. Duh"

   -- The type of the `do` statement is that of its last line.
   -- `return` is not a keyword, but merely a function
   return ("after action.\n") -- return :: String -> IO String


main :: IO ()
--main :: Int
main =

  do
    conn <- connect defaultConnectInfo
      { connectHost = "moita",
        connectUser = "mattei",
        connectPassword = "sidonie2",
        connectDatabase = "sidonie" }


-- we get all the Double Stars that have angular distance superior to a threshold of 1 second = 0.000278 degree

    rows <- query_ conn "SELECT Nom,distance FROM AngularDistance WHERE distance > 0.000278" 

    let lg = Prelude.length rows

    let tst = if lg > 1 then "some" else "one or zero"

    forM_ rows $ \(name,distance) ->
      putStrLn $  Text.unpack name ++ " " ++ show (distance :: Double)

-- before overwriting one database with the data of another 
-- we will get the Durchmusterung Number BD from Sidonie and WDS and compare them for a given name
-- Warning: there could be multiple result in WDS for a given entry name (due to components)

-- first we get the N��BD from sidonie

    let name = "A    20"
    
    let qry_head = "select `N�� BD` from sidonie.Coordonn��es where Nom = ?" :: Query
    let qry_head_WDS = "select DNUM from WDS where DISC = ?" :: Query

--    bd_rows <- query_ conn "select `N�� BD` from Coordonn��es where Nom = 'A    20'"

    bd_rows <- query conn qry_head (Only (name::String))

    bd_rows_WDS <- query conn qry_head_WDS (Only (name::String))

    putStrLn $ show bd_rows
    putStrLn $ show name

    let resLst = Prelude.map fromOnly bd_rows 

    let noBDtxt = fromOnly (Prelude.head bd_rows) :: Text 

    putStrLn $ show resLst
    
    putStrLn $ show noBDtxt
    
    forM_ bd_rows $ \(Only a) ->
      putStrLn $  Text.unpack a

    let noBDstr = Text.unpack noBDtxt :: String
    let noBDfp = read $ noBDstr :: Float

    putStr "noBDfp ="
    (putStrLn (show noBDfp))
    

    -- getBD conn name >>= (\noBD ->
    --                     --   putStrLn ("noBD + 1 = " ++ (show (noBD + 1))))
    --                         ((putStrLn . show) noBD))

    noBD <- getBD conn name
--    putStrLn ("noBD + 1 = " ++ (show (noBD + 1)))
    putStrLn ("noBD = " ++ (show noBD))
    
--    let noBDfp2 = read $ noBDstr2 :: Float

    result <- action
    putStrLn result
    
--    putStrLn $ show rows

    (putStr "Number of Binary Stars systems having angular distance superior to a threshold of 1 second = ")
    (putStrLn (show lg))

    let lstBD_WDS = getLstBD_WDS conn name
--    putStrLn (show lstBD_WDS)

    

    

--    let lg = Prelude.length bd_rows
--    putStrLn ("lg = " ++ (show lg))
    
    
    close conn

    print "Exit."

   
    
