package sftp

import (
	
	
)

// all incoming packets
type requestPacket interface {
	encoding.BinaryUnmarshaler
	id() uint32
}

type responsePacket interface {
	encoding.BinaryMarshaler
	id() uint32
}

// interfaces to group types
type hasPath interface {
	requestPacket
	getPath() string
}

type hasHandle interface {
	requestPacket
	getHandle() string
}

type notReadOnly interface {
	notReadOnly()
}

// // define types by adding methods
// hasPath
func ( *sshFxpLstatPacket) () string    { return .Path }
func ( *sshFxpStatPacket) () string     { return .Path }
func ( *sshFxpRmdirPacket) () string    { return .Path }
func ( *sshFxpReadlinkPacket) () string { return .Path }
func ( *sshFxpRealpathPacket) () string { return .Path }
func ( *sshFxpMkdirPacket) () string    { return .Path }
func ( *sshFxpSetstatPacket) () string  { return .Path }
func ( *sshFxpStatvfsPacket) () string  { return .Path }
func ( *sshFxpRemovePacket) () string   { return .Filename }
func ( *sshFxpRenamePacket) () string   { return .Oldpath }
func ( *sshFxpSymlinkPacket) () string  { return .Targetpath }
func ( *sshFxpOpendirPacket) () string  { return .Path }
func ( *sshFxpOpenPacket) () string     { return .Path }

func ( *sshFxpExtendedPacketPosixRename) () string { return .Oldpath }
func ( *sshFxpExtendedPacketHardlink) () string    { return .Oldpath }

// getHandle
func ( *sshFxpFstatPacket) () string    { return .Handle }
func ( *sshFxpFsetstatPacket) () string { return .Handle }
func ( *sshFxpReadPacket) () string     { return .Handle }
func ( *sshFxpWritePacket) () string    { return .Handle }
func ( *sshFxpReaddirPacket) () string  { return .Handle }
func ( *sshFxpClosePacket) () string    { return .Handle }

// notReadOnly
func ( *sshFxpWritePacket) ()               {}
func ( *sshFxpSetstatPacket) ()             {}
func ( *sshFxpFsetstatPacket) ()            {}
func ( *sshFxpRemovePacket) ()              {}
func ( *sshFxpMkdirPacket) ()               {}
func ( *sshFxpRmdirPacket) ()               {}
func ( *sshFxpRenamePacket) ()              {}
func ( *sshFxpSymlinkPacket) ()             {}
func ( *sshFxpExtendedPacketPosixRename) () {}
func ( *sshFxpExtendedPacketHardlink) ()    {}

// some packets with ID are missing id()
func ( *sshFxpDataPacket) () uint32   { return .ID }
func ( *sshFxpStatusPacket) () uint32 { return .ID }
func ( *sshFxpStatResponse) () uint32 { return .ID }
func ( *sshFxpNamePacket) () uint32   { return .ID }
func ( *sshFxpHandlePacket) () uint32 { return .ID }
func ( *StatVFS) () uint32            { return .ID }
func ( *sshFxVersionPacket) () uint32 { return 0 }

// take raw incoming packet data and build packet objects
func makePacket( rxPacket) (requestPacket, error) {
	var  requestPacket
	switch .pktType {
	case sshFxpInit:
		 = &sshFxInitPacket{}
	case sshFxpLstat:
		 = &sshFxpLstatPacket{}
	case sshFxpOpen:
		 = &sshFxpOpenPacket{}
	case sshFxpClose:
		 = &sshFxpClosePacket{}
	case sshFxpRead:
		 = &sshFxpReadPacket{}
	case sshFxpWrite:
		 = &sshFxpWritePacket{}
	case sshFxpFstat:
		 = &sshFxpFstatPacket{}
	case sshFxpSetstat:
		 = &sshFxpSetstatPacket{}
	case sshFxpFsetstat:
		 = &sshFxpFsetstatPacket{}
	case sshFxpOpendir:
		 = &sshFxpOpendirPacket{}
	case sshFxpReaddir:
		 = &sshFxpReaddirPacket{}
	case sshFxpRemove:
		 = &sshFxpRemovePacket{}
	case sshFxpMkdir:
		 = &sshFxpMkdirPacket{}
	case sshFxpRmdir:
		 = &sshFxpRmdirPacket{}
	case sshFxpRealpath:
		 = &sshFxpRealpathPacket{}
	case sshFxpStat:
		 = &sshFxpStatPacket{}
	case sshFxpRename:
		 = &sshFxpRenamePacket{}
	case sshFxpReadlink:
		 = &sshFxpReadlinkPacket{}
	case sshFxpSymlink:
		 = &sshFxpSymlinkPacket{}
	case sshFxpExtended:
		 = &sshFxpExtendedPacket{}
	default:
		return nil, fmt.Errorf("unhandled packet type: %s", .pktType)
	}
	if  := .UnmarshalBinary(.pktBytes);  != nil {
		// Return partially unpacked packet to allow callers to return
		// error messages appropriately with necessary id() method.
		return , 
	}
	return , nil
}