{-# LANGUAGE OverloadedStrings #-}

module Distribution.Cab.GenPaths (genPaths) where

import Control.Exception
import Control.Monad
import Data.List (isSuffixOf)
import Distribution.Cab.Utils (readGenericPackageDescription, unPackageName)
import Distribution.Package (pkgName, pkgVersion)
import Distribution.PackageDescription
import Distribution.Verbosity (silent)
import Distribution.Version
import System.Directory

genPaths :: IO ()
genPaths :: IO ()
genPaths = do
    (String
nm,Version
ver) <- IO String
getCabalFile IO String
-> (String -> IO (String, Version)) -> IO (String, Version)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> IO (String, Version)
getNameVersion
    let file :: String
file = String
"Paths_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".hs"
    String -> IO ()
check String
file IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> do
        String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Writing " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
file String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"..."
        String -> String -> IO ()
writeFile String
file (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"module Paths_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"  where\n"
                      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"import Data.Version\n"
                      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n"
                      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"version :: Version\n"
                      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"version = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
forall a. Show a => a -> String
show Version
ver String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n"
  where
    check :: String -> IO ()
check String
file = do
        Bool
exist <- String -> IO Bool
doesFileExist String
file
        Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
exist (IO () -> IO ()) -> (String -> IO ()) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IOError -> IO ()
forall e a. Exception e => e -> IO a
throwIO (IOError -> IO ()) -> (String -> IOError) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IOError
userError (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
file String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" already exists"

getNameVersion :: FilePath -> IO (String,Version)
getNameVersion :: String -> IO (String, Version)
getNameVersion String
file = do
    GenericPackageDescription
desc <- Verbosity -> String -> IO GenericPackageDescription
readGenericPackageDescription Verbosity
silent String
file
    let pkg :: PackageIdentifier
pkg = PackageDescription -> PackageIdentifier
package (PackageDescription -> PackageIdentifier)
-> (GenericPackageDescription -> PackageDescription)
-> GenericPackageDescription
-> PackageIdentifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenericPackageDescription -> PackageDescription
packageDescription (GenericPackageDescription -> PackageIdentifier)
-> GenericPackageDescription -> PackageIdentifier
forall a b. (a -> b) -> a -> b
$ GenericPackageDescription
desc
        nm :: String
nm = PackageName -> String
unPackageName (PackageName -> String) -> PackageName -> String
forall a b. (a -> b) -> a -> b
$ PackageIdentifier -> PackageName
pkgName PackageIdentifier
pkg
        name :: String
name = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map (Char -> Char -> Char -> Char
forall p. Eq p => p -> p -> p -> p
trans Char
'-' Char
'_') String
nm
        version :: Version
version = PackageIdentifier -> Version
pkgVersion PackageIdentifier
pkg
    (String, Version) -> IO (String, Version)
forall (m :: * -> *) a. Monad m => a -> m a
return (String
name, Version
version)
  where
    trans :: p -> p -> p -> p
trans p
c1 p
c2 p
c
      | p
c p -> p -> Bool
forall a. Eq a => a -> a -> Bool
== p
c1   = p
c2
      | Bool
otherwise = p
c

getCabalFile :: IO FilePath
getCabalFile :: IO String
getCabalFile = do
    [String]
cnts <- ((String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
isCabal ([String] -> [String]) -> IO [String] -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO [String]
getDirectoryContents String
".")
            IO [String] -> ([String] -> IO [String]) -> IO [String]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (String -> IO Bool) -> [String] -> IO [String]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM String -> IO Bool
doesFileExist
    case [String]
cnts of
        []      -> IOError -> IO String
forall e a. Exception e => e -> IO a
throwIO (IOError -> IO String) -> IOError -> IO String
forall a b. (a -> b) -> a -> b
$ String -> IOError
userError String
"Cabal file does not exist"
        String
cfile:[String]
_ -> String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
cfile
  where
    isCabal :: String -> Bool
    isCabal :: String -> Bool
isCabal String
nm = String
".cabal" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
nm Bool -> Bool -> Bool
&& String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
nm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
6