package sshfx

// ClosePacket defines the SSH_FXP_CLOSE packet.
type ClosePacket struct {
	Handle string
}

// Type returns the SSH_FXP_xy value associated with this packet type.
func ( *ClosePacket) () PacketType {
	return PacketTypeClose
}

// MarshalPacket returns p as a two-part binary encoding of p.
func ( *ClosePacket) ( uint32,  []byte) (,  []byte,  error) {
	 := NewBuffer()
	if .Cap() < 9 {
		 := 4 + len(.Handle) // string(handle)
		 = NewMarshalBuffer()
	}

	.StartPacket(PacketTypeClose, )
	.AppendString(.Handle)

	return .Packet()
}

// UnmarshalPacketBody unmarshals the packet body from the given Buffer.
// It is assumed that the uint32(request-id) has already been consumed.
func ( *ClosePacket) ( *Buffer) ( error) {
	* = ClosePacket{
		Handle: .ConsumeString(),
	}

	return .Err
}

// ReadPacket defines the SSH_FXP_READ packet.
type ReadPacket struct {
	Handle string
	Offset uint64
	Length uint32
}

// Type returns the SSH_FXP_xy value associated with this packet type.
func ( *ReadPacket) () PacketType {
	return PacketTypeRead
}

// MarshalPacket returns p as a two-part binary encoding of p.
func ( *ReadPacket) ( uint32,  []byte) (,  []byte,  error) {
	 := NewBuffer()
	if .Cap() < 9 {
		// string(handle) + uint64(offset) + uint32(len)
		 := 4 + len(.Handle) + 8 + 4
		 = NewMarshalBuffer()
	}

	.StartPacket(PacketTypeRead, )
	.AppendString(.Handle)
	.AppendUint64(.Offset)
	.AppendUint32(.Length)

	return .Packet()
}

// UnmarshalPacketBody unmarshals the packet body from the given Buffer.
// It is assumed that the uint32(request-id) has already been consumed.
func ( *ReadPacket) ( *Buffer) ( error) {
	* = ReadPacket{
		Handle: .ConsumeString(),
		Offset: .ConsumeUint64(),
		Length: .ConsumeUint32(),
	}

	return .Err
}

// WritePacket defines the SSH_FXP_WRITE packet.
type WritePacket struct {
	Handle string
	Offset uint64
	Data   []byte
}

// Type returns the SSH_FXP_xy value associated with this packet type.
func ( *WritePacket) () PacketType {
	return PacketTypeWrite
}

// MarshalPacket returns p as a two-part binary encoding of p.
func ( *WritePacket) ( uint32,  []byte) (,  []byte,  error) {
	 := NewBuffer()
	if .Cap() < 9 {
		// string(handle) + uint64(offset) + uint32(len(data)); data content in payload
		 := 4 + len(.Handle) + 8 + 4
		 = NewMarshalBuffer()
	}

	.StartPacket(PacketTypeWrite, )
	.AppendString(.Handle)
	.AppendUint64(.Offset)
	.AppendUint32(uint32(len(.Data)))

	return .Packet(.Data)
}

// UnmarshalPacketBody unmarshals the packet body from the given Buffer.
// It is assumed that the uint32(request-id) has already been consumed.
//
// If p.Data is already populated, and of sufficient length to hold the data,
// then this will copy the data into that byte slice.
//
// If p.Data has a length insufficient to hold the data,
// then this will make a new slice of sufficient length, and copy the data into that.
//
// This means this _does not_ alias any of the data buffer that is passed in.
func ( *WritePacket) ( *Buffer) ( error) {
	* = WritePacket{
		Handle: .ConsumeString(),
		Offset: .ConsumeUint64(),
		Data:   .ConsumeByteSliceCopy(.Data),
	}

	return .Err
}

// FStatPacket defines the SSH_FXP_FSTAT packet.
type FStatPacket struct {
	Handle string
}

// Type returns the SSH_FXP_xy value associated with this packet type.
func ( *FStatPacket) () PacketType {
	return PacketTypeFStat
}

// MarshalPacket returns p as a two-part binary encoding of p.
func ( *FStatPacket) ( uint32,  []byte) (,  []byte,  error) {
	 := NewBuffer()
	if .Cap() < 9 {
		 := 4 + len(.Handle) // string(handle)
		 = NewMarshalBuffer()
	}

	.StartPacket(PacketTypeFStat, )
	.AppendString(.Handle)

	return .Packet()
}

// UnmarshalPacketBody unmarshals the packet body from the given Buffer.
// It is assumed that the uint32(request-id) has already been consumed.
func ( *FStatPacket) ( *Buffer) ( error) {
	* = FStatPacket{
		Handle: .ConsumeString(),
	}

	return .Err
}

// FSetstatPacket defines the SSH_FXP_FSETSTAT packet.
type FSetstatPacket struct {
	Handle string
	Attrs  Attributes
}

// Type returns the SSH_FXP_xy value associated with this packet type.
func ( *FSetstatPacket) () PacketType {
	return PacketTypeFSetstat
}

// MarshalPacket returns p as a two-part binary encoding of p.
func ( *FSetstatPacket) ( uint32,  []byte) (,  []byte,  error) {
	 := NewBuffer()
	if .Cap() < 9 {
		 := 4 + len(.Handle) + .Attrs.Len() // string(handle) + ATTRS(attrs)
		 = NewMarshalBuffer()
	}

	.StartPacket(PacketTypeFSetstat, )
	.AppendString(.Handle)

	.Attrs.MarshalInto()

	return .Packet()
}

// UnmarshalPacketBody unmarshals the packet body from the given Buffer.
// It is assumed that the uint32(request-id) has already been consumed.
func ( *FSetstatPacket) ( *Buffer) ( error) {
	* = FSetstatPacket{
		Handle: .ConsumeString(),
	}

	return .Attrs.UnmarshalFrom()
}

// ReadDirPacket defines the SSH_FXP_READDIR packet.
type ReadDirPacket struct {
	Handle string
}

// Type returns the SSH_FXP_xy value associated with this packet type.
func ( *ReadDirPacket) () PacketType {
	return PacketTypeReadDir
}

// MarshalPacket returns p as a two-part binary encoding of p.
func ( *ReadDirPacket) ( uint32,  []byte) (,  []byte,  error) {
	 := NewBuffer()
	if .Cap() < 9 {
		 := 4 + len(.Handle) // string(handle)
		 = NewMarshalBuffer()
	}

	.StartPacket(PacketTypeReadDir, )
	.AppendString(.Handle)

	return .Packet()
}

// UnmarshalPacketBody unmarshals the packet body from the given Buffer.
// It is assumed that the uint32(request-id) has already been consumed.
func ( *ReadDirPacket) ( *Buffer) ( error) {
	* = ReadDirPacket{
		Handle: .ConsumeString(),
	}

	return .Err
}