    {-# LANGUAGE CPP  #-}
    {-# LANGUAGE Safe #-}
    {-
    Copyright (c) 2005-2011 John Goerzen <jgoerzen@complete.org>

    All rights reserved.

    For license and copyright information, see the file LICENSE
    -}

    {- |
       Module     : System.IO.StatCompat
       Copyright  : Copyright (C) 2005-2011 John Goerzen
       SPDX-License-Identifier: BSD-3-Clause

       Stability  : stable
       Portability: portable

    Provide a stat-like structure for use in MissingH.  Especially
    useful with HVFS and on Windows.  See also "System.IO.WindowsCompat".

    -}

    module System.IO.StatCompat where

    import safe System.Posix.Consts
        ( blockSpecialMode,
          characterSpecialMode,
          namedPipeMode,
          regularFileMode,
          directoryMode,
          fileTypeModes,
          socketMode,
          symbolicLinkMode )
    import safe System.Posix.Types
        ( DeviceID,
          EpochTime,
          FileID,
          FileMode,
          FileOffset )

    #if !(defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__))
    import safe System.Posix.Types ( LinkCount, UserID, GroupID )
    import safe System.Posix.Files ( intersectFileModes )
    #else
    import safe Data.Bits          ( (.&.) )

    type LinkCount = Int
    type UserID = Int
    type GroupID = Int

    intersectFileModes :: FileMode -> FileMode -> FileMode
    intersectFileModes m1 m2 = m1 .&. m2
    #endif

    data FileStatusCompat =
        FileStatusCompat {FileStatusCompat -> DeviceID
    deviceID         :: DeviceID,
                          FileStatusCompat -> FileID
    fileID           :: FileID,
                          FileStatusCompat -> FileMode
    fileMode         :: FileMode,
                          FileStatusCompat -> LinkCount
    linkCount        :: LinkCount,
                          FileStatusCompat -> UserID
    fileOwner        :: UserID,
                          FileStatusCompat -> GroupID
    fileGroup        :: GroupID,
                          FileStatusCompat -> DeviceID
    specialDeviceID  :: DeviceID,
                          FileStatusCompat -> FileOffset
    fileSize         :: FileOffset,
                          FileStatusCompat -> EpochTime
    accessTime       :: EpochTime,
                          FileStatusCompat -> EpochTime
    modificationTime :: EpochTime,
                          FileStatusCompat -> EpochTime
    statusChangeTime :: EpochTime
                         }

    sc_helper :: FileMode -> FileStatusCompat -> Bool
    sc_helper :: FileMode -> FileStatusCompat -> Bool
    sc_helper FileMode
    comp FileStatusCompat
    stat =
        (FileStatusCompat -> FileMode
    fileMode FileStatusCompat
    stat FileMode -> FileMode -> FileMode
    `intersectFileModes` FileMode
    fileTypeModes) FileMode -> FileMode -> Bool
    forall a. Eq a => a -> a -> Bool
    == FileMode
    comp

    isBlockDevice,isCharacterDevice,isNamedPipe,isRegularFile,isDirectory,isSymbolicLink,isSocket :: FileStatusCompat -> Bool
    isBlockDevice :: FileStatusCompat -> Bool
    isBlockDevice = FileMode -> FileStatusCompat -> Bool
    sc_helper FileMode
    blockSpecialMode
    isCharacterDevice :: FileStatusCompat -> Bool
    isCharacterDevice = FileMode -> FileStatusCompat -> Bool
    sc_helper FileMode
    characterSpecialMode
    isNamedPipe :: FileStatusCompat -> Bool
    isNamedPipe = FileMode -> FileStatusCompat -> Bool
    sc_helper FileMode
    namedPipeMode
    isRegularFile :: FileStatusCompat -> Bool
    isRegularFile = FileMode -> FileStatusCompat -> Bool
    sc_helper FileMode
    regularFileMode
    isDirectory :: FileStatusCompat -> Bool
    isDirectory = FileMode -> FileStatusCompat -> Bool
    sc_helper FileMode
    directoryMode
    isSymbolicLink :: FileStatusCompat -> Bool
    isSymbolicLink = FileMode -> FileStatusCompat -> Bool
    sc_helper FileMode
    symbolicLinkMode
    isSocket :: FileStatusCompat -> Bool
    isSocket = FileMode -> FileStatusCompat -> Bool
    sc_helper FileMode
    socketMode