package sshfx

// LStatPacket defines the SSH_FXP_LSTAT packet.
type LStatPacket struct {
	Path string
}

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

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

	.StartPacket(PacketTypeLStat, )
	.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 ( *LStatPacket) ( *Buffer) ( error) {
	* = LStatPacket{
		Path: .ConsumeString(),
	}

	return .Err
}

// SetstatPacket defines the SSH_FXP_SETSTAT packet.
type SetstatPacket struct {
	Path  string
	Attrs Attributes
}

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

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

	.StartPacket(PacketTypeSetstat, )
	.AppendString(.Path)

	.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 ( *SetstatPacket) ( *Buffer) ( error) {
	* = SetstatPacket{
		Path: .ConsumeString(),
	}

	return .Attrs.UnmarshalFrom()
}

// RemovePacket defines the SSH_FXP_REMOVE packet.
type RemovePacket struct {
	Path string
}

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

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

	.StartPacket(PacketTypeRemove, )
	.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 ( *RemovePacket) ( *Buffer) ( error) {
	* = RemovePacket{
		Path: .ConsumeString(),
	}

	return .Err
}

// MkdirPacket defines the SSH_FXP_MKDIR packet.
type MkdirPacket struct {
	Path  string
	Attrs Attributes
}

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

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

	.StartPacket(PacketTypeMkdir, )
	.AppendString(.Path)

	.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 ( *MkdirPacket) ( *Buffer) ( error) {
	* = MkdirPacket{
		Path: .ConsumeString(),
	}

	return .Attrs.UnmarshalFrom()
}

// RmdirPacket defines the SSH_FXP_RMDIR packet.
type RmdirPacket struct {
	Path string
}

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

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

	.StartPacket(PacketTypeRmdir, )
	.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 ( *RmdirPacket) ( *Buffer) ( error) {
	* = RmdirPacket{
		Path: .ConsumeString(),
	}

	return .Err
}

// RealPathPacket defines the SSH_FXP_REALPATH packet.
type RealPathPacket struct {
	Path string
}

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

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

	.StartPacket(PacketTypeRealPath, )
	.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 ( *RealPathPacket) ( *Buffer) ( error) {
	* = RealPathPacket{
		Path: .ConsumeString(),
	}

	return .Err
}

// StatPacket defines the SSH_FXP_STAT packet.
type StatPacket struct {
	Path string
}

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

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

	.StartPacket(PacketTypeStat, )
	.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 ( *StatPacket) ( *Buffer) ( error) {
	* = StatPacket{
		Path: .ConsumeString(),
	}

	return .Err
}

// RenamePacket defines the SSH_FXP_RENAME packet.
type RenamePacket struct {
	OldPath string
	NewPath string
}

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

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

	.StartPacket(PacketTypeRename, )
	.AppendString(.OldPath)
	.AppendString(.NewPath)

	return .Packet()
}

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

	return .Err
}

// ReadLinkPacket defines the SSH_FXP_READLINK packet.
type ReadLinkPacket struct {
	Path string
}

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

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

	.StartPacket(PacketTypeReadLink, )
	.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 ( *ReadLinkPacket) ( *Buffer) ( error) {
	* = ReadLinkPacket{
		Path: .ConsumeString(),
	}

	return .Err
}

// SymlinkPacket defines the SSH_FXP_SYMLINK packet.
//
// The order of the arguments to the SSH_FXP_SYMLINK method was inadvertently reversed.
// Unfortunately, the reversal was not noticed until the server was widely deployed.
// Covered in Section 4.1 of https://github.com/openssh/openssh-portable/blob/master/PROTOCOL
type SymlinkPacket struct {
	LinkPath   string
	TargetPath string
}

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

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

	.StartPacket(PacketTypeSymlink, )

	// Arguments were inadvertently reversed.
	.AppendString(.TargetPath)
	.AppendString(.LinkPath)

	return .Packet()
}

// UnmarshalPacketBody unmarshals the packet body from the given Buffer.
// It is assumed that the uint32(request-id) has already been consumed.
func ( *SymlinkPacket) ( *Buffer) ( error) {
	* = SymlinkPacket{
		// Arguments were inadvertently reversed.
		TargetPath: .ConsumeString(),
		LinkPath:   .ConsumeString(),
	}

	return .Err
}