content: {-# LANGUAGE RecordWildCards   #-}
  {-# LANGUAGE OverloadedStrings #-}
  
  module Stack2nix.External.Cabal2nix (
    cabal2nix
    ) where
  
  import           Cabal2nix                   (cabal2nixWithDB, parseArgs, optNixpkgsIdentifier, Options)
  import           Control.Lens
  import           Data.Bool                   (bool)
  import           Data.Maybe                  (fromMaybe, maybeToList)
  import           Data.Text                   (Text, unpack)
  import qualified Distribution.Nixpkgs.Haskell.Hackage as DB
  import           Distribution.Nixpkgs.Haskell.Derivation (Derivation)
  import           Distribution.PackageDescription (unFlagName)
  import           Distribution.System         (Platform(..), Arch(..), OS(..))
  import           Language.Nix
  import           System.IO                   (hPutStrLn, stderr)
  import           Stack.Types.Version         (Version)
  import           Stack2nix.Types             (Args (..), Flags)
  
  import           Text.PrettyPrint.HughesPJClass (Doc)
  
  cabal2nix :: Args -> Version -> FilePath -> Maybe Text -> Maybe FilePath -> Flags -> DB.HackageDB -> IO (Either Doc Derivation)
  cabal2nix Args{..} ghcVersion uri commit subpath flags hackageDB = do
    let runCmdArgs = args $ fromMaybe "." subpath
    hPutStrLn stderr $ unwords ("+ cabal2nix":runCmdArgs)
    options <- parseArgs runCmdArgs
    cabal2nixWithDB hackageDB $ cabalOptions options
  
    where
      args :: FilePath -> [String]
      args dir = concat
        [ maybe [] (\c -> ["--revision", unpack c]) commit
        , maybeToList argCabal2nixArgs
        , ["--subpath", dir]
        , ["--system", fromCabalPlatform argPlatform]
        , ["--compiler", "ghc-" ++ show ghcVersion]
        , ["-f" ++ bool "-" "" enable ++ unFlagName f | (f, enable) <- flags]
        , [uri]
        ]
  
  -- Override default nixpkgs resolver to do pkgs.attr instead of attr
  cabalOptions :: Options -> Options
  cabalOptions options =
    options {
      optNixpkgsIdentifier = \i -> Just (binding # (i, path # ["pkgs", i]))
    }
  
  -- | Copied (and modified) from src/Distribution/Nixpkgs/Meta.hs
  fromCabalPlatform :: Platform -> String
  fromCabalPlatform (Platform I386 Linux)   = "i686-linux"
  fromCabalPlatform (Platform X86_64 Linux) = "x86_64-linux"
  fromCabalPlatform (Platform X86_64 OSX)   = "x86_64-darwin"
  fromCabalPlatform (Platform AArch64 Linux)= "aarch64-linux"
  fromCabalPlatform p                       = error ("fromCabalPlatform: invalid Nix platform" ++ show p)
  