package sshfx

// SSH_FXF_* flags.
const (
	FlagRead      = 1 << iota // SSH_FXF_READ
	FlagWrite                 // SSH_FXF_WRITE
	FlagAppend                // SSH_FXF_APPEND
	FlagCreate                // SSH_FXF_CREAT
	FlagTruncate              // SSH_FXF_TRUNC
	FlagExclusive             // SSH_FXF_EXCL
)

// OpenPacket defines the SSH_FXP_OPEN packet.
type OpenPacket struct {
	Filename string
	PFlags   uint32
	Attrs    Attributes
}

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

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

	.StartPacket(PacketTypeOpen, )
	.AppendString(.Filename)
	.AppendUint32(.PFlags)

	.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 ( *OpenPacket) ( *Buffer) ( error) {
	* = OpenPacket{
		Filename: .ConsumeString(),
		PFlags:   .ConsumeUint32(),
	}

	return .Attrs.UnmarshalFrom()
}

// OpenDirPacket defines the SSH_FXP_OPENDIR packet.
type OpenDirPacket struct {
	Path string
}

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

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

	.StartPacket(PacketTypeOpenDir, )
	.AppendString(.Path)

	return .Packet()
}

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

	return .Err
}