namespace Tinkerforge
{
    public static class ERED
    {
        public static (long Lifetime, byte ErrorCode, int SessionId) CreateSession(this BrickRED red, long lifetime)
        {
            red.CreateSession(lifetime, out byte errorCode, out int sessionId);
            return (lifetime, errorCode, sessionId);
        }

        public static (long LengthToReserve, string Buffer, int SessionId, byte ErrorCode, int StringId) AllocateString(
            this BrickRED red, long lengthToReserve, string buffer, int sessionId)
        {
            red.AllocateString(lengthToReserve, buffer, sessionId, out byte errorCode, out int stringId);
            return (lengthToReserve, buffer, sessionId, errorCode, stringId);
        }

        public static (int StringId, byte ErrorCode, long Length) GetStringLength(this BrickRED red, int stringId)
        {
            red.GetStringLength(stringId, out byte errorCode, out long length);
            return (stringId, errorCode, length);
        }

        public static (int StringId, long Offset, byte ErrorCode, string Buffer) GetStringChunk(this BrickRED red,
            int stringId, long offset)
        {
            red.GetStringChunk(stringId, offset, out byte errorCode, out string buffer);
            return (stringId, offset, errorCode, buffer);
        }

        public static (int LengthToReserve, int SessionId, byte ErrorCode, int ListId) AllocateList(this BrickRED red,
            int lengthToReserve, int sessionId)
        {
            red.AllocateList(lengthToReserve, sessionId, out byte errorCode, out int listId);
            return (lengthToReserve, sessionId, errorCode, listId);
        }

        public static (int ListId, byte ErrorCode, int Length) GetListLength(this BrickRED red, int listId)
        {
            red.GetListLength(listId, out byte errorCode, out int length);
            return (listId, errorCode, length);
        }

        public static (int ListId, int Index, int SessionId, byte ErrorCode, int ItemObjectId, byte Type) GetListItem(
            this BrickRED red, int listId, int index, int sessionId)
        {
            red.GetListItem(listId, index, sessionId, out byte errorCode, out int itemObjectId, out byte type);
            return (listId, index, sessionId, errorCode, itemObjectId, type);
        }

        public static (int NameStringId, long Flags, int Permissions, long UId, long GId, int SessionId, byte ErrorCode,
            int FileId) OpenFile(this BrickRED red, int nameStringId, long flags, int permissions, long uid, long gid,
                int sessionId)
        {
            red.OpenFile(nameStringId, flags, permissions, uid, gid, sessionId, out byte errorCode, out int fileId);
            return (nameStringId, flags, permissions, uid, gid, sessionId, errorCode, fileId);
        }

        public static (long Flags, long Length, int SessionId, byte ErrorCode, int FileId) CreatePipe(this BrickRED red,
            long flags, long length, int sessionId)
        {
            red.CreatePipe(flags, length, sessionId, out byte errorCode, out int fileId);
            return (flags, length, sessionId, errorCode, fileId);
        }

        public static (int FileId, int SessionId, byte ErrorCode, byte Type, int NameStringId, long Flags, int
            Permissions, long UId, long GId, long Length, long AccessTimestamp, long ModificationTimestamp, long
            StatusChangeTimestamp) GetFileInfo(this BrickRED red, int fileId, int sessionId)
        {
            red.GetFileInfo(fileId, sessionId, out byte errorCode, out byte type, out int nameStringId, out long flags,
                out int permissions, out long uid, out long gid, out long length, out long accessTimestamp,
                out long modificationTimestamp, out long statusChangeTimestamp);
            return (fileId, sessionId, errorCode, type, nameStringId, flags, permissions, uid, gid, length,
                accessTimestamp, modificationTimestamp, statusChangeTimestamp);
        }

        public static (int FileId, byte LengthToRead, byte ErrorCode, byte[] Buffer, byte LengthRead) ReadFile(
            this BrickRED red, int fileId, byte lengthToRead)
        {
            red.ReadFile(fileId, lengthToRead, out byte errorCode, out byte[] buffer, out byte lengthRead);
            return (fileId, lengthToRead, errorCode, buffer, lengthRead);
        }

        public static (int FileId, byte[] Buffer, byte LengthToWrite, byte ErrorCode, byte LengthWritten) WriteFile(
            this BrickRED red, int fileId, byte[] buffer, byte lengthToWrite)
        {
            red.WriteFile(fileId, buffer, lengthToWrite, out byte errorCode, out byte lengthWritten);
            return (fileId, buffer, lengthToWrite, errorCode, lengthWritten);
        }

        public static (int FileId, long Offset, byte Origin, byte ErrorCode, long Position) SetFilePosition(
            this BrickRED red, int fileId, long offset, byte origin)
        {
            red.SetFilePosition(fileId, offset, origin, out byte errorCode, out long position);
            return (fileId, offset, origin, errorCode, position);
        }

        public static (int FileId, byte ErrorCode, long Position) GetFilePosition(this BrickRED red, int fileId)
        {
            red.GetFilePosition(fileId, out byte errorCode, out long position);
            return (fileId, errorCode, position);
        }

        public static (int FileId, byte ErrorCode, int Events) GetFileEvents(this BrickRED red, int fileId)
        {
            red.GetFileEvents(fileId, out byte errorCode, out int events);
            return (fileId, errorCode, events);
        }

        public static (int NameStringId, int SessionId, byte ErrorCode, int DirectoryId) OpenDirectory(
            this BrickRED red, int nameStringId, int sessionId)
        {
            red.OpenDirectory(nameStringId, sessionId, out byte errorCode, out int directoryId);
            return (nameStringId, sessionId, errorCode, directoryId);
        }

        public static (int DirectoryId, int SessionId, byte ErrorCode, int NameStringId) GetDirectoryName(
            this BrickRED red, int directoryId, int sessionId)
        {
            red.GetDirectoryName(directoryId, sessionId, out byte errorCode, out int nameStringId);
            return (directoryId, sessionId, errorCode, nameStringId);
        }

        public static (int DirectoryId, int SessionId, byte ErrorCode, int NameStringId, byte Type)
            GetNextDirectoryEntry(this BrickRED red, int directoryId, int sessionId)
        {
            red.GetNextDirectoryEntry(directoryId, sessionId, out byte errorCode, out int nameStringId, out byte type);
            return (directoryId, sessionId, errorCode, nameStringId, type);
        }

        public static (int SessionId, byte ErrorCode, int ProcessesListId) GetProcesses(this BrickRED red,
            int sessionId)
        {
            red.GetProcesses(sessionId, out byte errorCode, out int processesListId);
            return (sessionId, errorCode, processesListId);
        }

        public static (int ExecutableStringId, int ArgumentsListId, int EnvironmentListId, int WorkingDirectoryStringId,
            long UId, long GId, int StdinFileId, int StdoutFileId, int StderrFileId, int SessionId, byte ErrorCode, int
            ProcessId) SpawnProcess(this BrickRED red, int executableStringId, int argumentsListId, int environmentListId,
                int workingDirectoryStringId, long uid, long gid, int stdinFileId, int stdoutFileId, int stderrFileId,
                int sessionId)
        {
            red.SpawnProcess(executableStringId, argumentsListId, environmentListId, workingDirectoryStringId, uid, gid,
                stdinFileId, stdoutFileId, stderrFileId, sessionId, out byte errorCode, out int processId);
            return (executableStringId, argumentsListId, environmentListId, workingDirectoryStringId, uid, gid,
                stdinFileId, stdoutFileId, stderrFileId, sessionId, errorCode, processId);
        }

        public static (int ProcessId, int SessionId, byte ErrorCode, int ExecutableStringId, int ArgumentsListId, int
            EnvironmentListId, int WorkingDirectoryStringId) GetProcessCommand(this BrickRED red, int processId, int sessionId)
        {
            red.GetProcessCommand(processId, sessionId, out byte errorCode, out int executableStringId,
                out int argumentsListId, out int environmentListId, out int workingDirectoryStringId);
            return (processId, sessionId, errorCode, executableStringId, argumentsListId, environmentListId,
                workingDirectoryStringId);
        }

        public static (int ProcessId, byte ErrorCode, long PId, long UId, long GId) GetProcessIdentity(
            this BrickRED red, int processId)
        {
            red.GetProcessIdentity(processId, out byte errorCode, out long pid, out long uid, out long gid);
            return (processId, errorCode, pid, uid, gid);
        }

        public static (int ProcessId, int SessionId, byte ErrorCode, int StdinFileId, int StdoutFileId, int StderrFileId
            ) GetProcessStdio(this BrickRED red, int processId, int sessionId)
        {
            red.GetProcessStdio(processId, sessionId, out byte errorCode, out int stdinFileId, out int stdoutFileId, out int stderrFileId);
            return (processId, sessionId, errorCode, stdinFileId, stdoutFileId, stderrFileId);
        }

        public static (int ProcessId, byte ErrorCode, byte State, long Timestamp, byte ExitCode) GetProcessState(
            this BrickRED red, int processId)
        {
            red.GetProcessState(processId, out byte errorCode, out byte state, out long timestamp, out byte exitCode);
            return (processId, errorCode, state, timestamp, exitCode);
        }

        public static (int SessionId, byte ErrorCode, int ProgramsListId) GetPrograms(this BrickRED red, int sessionId)
        {
            red.GetPrograms(sessionId, out byte errorCode, out int programsListId);
            return (sessionId, errorCode, programsListId);
        }

        public static (int IdentifierStringId, int SessionId, byte ErrorCode, int ProgramId) DefineProgram(
            this BrickRED red, int identifierStringId, int sessionId)
        {
            red.DefineProgram(identifierStringId, sessionId, out byte errorCode, out int programId);
            return (identifierStringId, sessionId, errorCode, programId);
        }

        public static (int ProgramId, int SessionId, byte ErrorCode, int IdentifierStringId) GetProgramIdentifier(
            this BrickRED red, int programId, int sessionId)
        {
            red.GetProgramIdentifier(programId, sessionId, out byte errorCode, out int identifierStringId);
            return (programId, sessionId, errorCode, identifierStringId);
        }

        public static (int ProgramId, int SessionId, byte ErrorCode, int RootDirectoryStringId) GetProgramRootDirectory(
            this BrickRED red, int programId, int sessionId)
        {
            red.GetProgramRootDirectory( programId, sessionId, out byte errorCode, out int rootDirectoryStringId);
            return (programId, sessionId, errorCode, rootDirectoryStringId);
        }

        public static (int ProgramId, int SessionId, byte ErrorCode, int ExecutableStringId, int ArgumentsListId, int
            EnvironmentListId, int WorkingDirectoryStringId) GetProgramCommand(this BrickRED red, int programId,
                int sessionId)
        {
            red.GetProgramCommand(programId, sessionId, out byte errorCode, out int executableStringId,
                out int argumentsListId, out int environmentListId, out int workingDirectoryStringId);
            return (programId, sessionId, errorCode, executableStringId, argumentsListId, environmentListId,
                workingDirectoryStringId);

        }

        public static (int ProgramId, int SessionId, byte ErrorCode, byte StdinRedirection, int StdinFileNameStringId,
            byte StdoutRedirection, int StdoutFileNameStringId, byte StderrRedirection, int StderrFileNameStringId)
            GetProgramStdioRedirection(this BrickRED red, int programId, int sessionId)
        {
            red.GetProgramStdioRedirection(programId, sessionId, out byte errorCode, out byte stdinRedirection,
                out int stdinFileNameStringId, out byte stdoutRedirection, out int stdoutFileNameStringId,
                out byte stderrRedirection, out int stderrFileNameStringId);
            return (programId, sessionId, errorCode, stdinRedirection, stdinFileNameStringId, stdoutRedirection,
                stdoutFileNameStringId, stderrRedirection, stderrFileNameStringId);
        }

        public static (int ProgramId, int SessionId, byte ErrorCode, byte StartMode, bool ContinueAfterError, long
            StartInterval, int StartFieldsStringId) GetProgramSchedule(this BrickRED red, int programId, int sessionId)
        {
            red.GetProgramSchedule(programId, sessionId, out byte errorCode, out byte startMode,
                out bool continueAfterError, out long startInterval, out int startFieldsStringId);
            return (programId, sessionId, errorCode, startMode, continueAfterError, startInterval, startFieldsStringId);
        }

        public static (int ProgramId, int SessionId, byte ErrorCode, byte State, long Timestamp, int MessageStringId)
            GetProgramSchedulerState(this BrickRED red, int programId, int sessionId)
        {
            red.GetProgramSchedulerState(programId, sessionId, out byte errorCode, out byte state, out long timestamp,
                out int messageStringId);
            return (programId, sessionId, errorCode, state, timestamp, messageStringId);
        }

        public static (int ProgramId, int SessionId, byte ErrorCode, int ProcessId, long Timestamp)
            GetLastSpawnedProgramProcess(this BrickRED red, int programId, int sessionId)
        {
            red.GetLastSpawnedProgramProcess(programId, sessionId, out byte errorCode, out int processId,
                out long timestamp);
            return (programId, sessionId, errorCode, processId, timestamp);
        }

        public static (int ProgramId, int SessionId, byte ErrorCode, int NamesListId) GetCustomProgramOptionNames(
            this BrickRED red, int programId, int sessionId)
        {
            red.GetCustomProgramOptionNames( programId, sessionId, out byte errorCode, out int namesListId);
            return (programId, sessionId, errorCode, namesListId);
        }

        public static (int ProgramId, int NameStringId, int SessionId, byte ErrorCode, int ValueStringId)
            GetCustomProgramOptionValue(this BrickRED red, int programId, int nameStringId, int sessionId)
        {
            red.GetCustomProgramOptionValue(programId, nameStringId, sessionId, out byte errorCode,
                out int valueStringId);
            return (programId, nameStringId, sessionId, errorCode, valueStringId);
        }


















    }
}
