#ifndef INCLUDED_BOBCAT_PIPE_
#define INCLUDED_BOBCAT_PIPE_

#include <bobcat/fswap>
#include <bobcat/exception>

namespace FBB
{

class Pipe
{
    int d_fd[2];

    protected:
        enum  RW
        {
            READ,
            WRITE
        };

    public:
        Pipe();                                                 // 1.cc
        Pipe(Pipe &&tmp);                                       // 2.cc
        explicit Pipe(int const *fd);     // fd: must be 2 FDs     3.cc
        explicit Pipe(bool initialize);                         // 4.cc

        // ~Pipe(); removed from the interface as it's implementation was
        //          empty and this class is not a Base class having virtual
        //          members

        Pipe &operator=(Pipe &&tmp);

        void close();                           // close the fds  1.cc
        void closeReadFd();                                     // .f
        void closeWriteFd();                                    // .f

        int readFd() const;                                     // .f
        void readFrom(int filedescriptor);
        void readFrom(int const *filedescriptor, size_t nSwallow);
        int readOnly();                     // closes the write FD
                                            // closes the FDs, sets read FD
        int readOnlyFd();                   // to -1, returns the original FD


                                            // closes the npipes
        void reset();                       // and reopens them         1.cc

                                            // closes the npipes and reopens 
                                            // them with the provided 2
        void reset(int const *fds);         // read/write file descr.   2.cc


        void swap(Pipe &other);

        int writeFd() const;                                    // .f
        int writeOnly();                // closes the read FD
        int writeOnlyFd();                // as readOnlyFd, using the write FD
        void writtenBy(int filedescriptor);
        void writtenBy(int const *filedescr, size_t nSwallow = 2);

    protected:
        void close(RW rw);                                      // 2.cc
};

inline void Pipe::closeReadFd()
{
    close(READ);
}
inline void Pipe::closeWriteFd()
{
    close(WRITE);
}
inline int Pipe::readFd() const
{
    return d_fd[READ];
}
inline void Pipe::swap(Pipe &other)
{
    FBB::fswap(*this, other);
}
inline int Pipe::writeFd() const
{
    return d_fd[WRITE];
}

} // FBB

#endif
