package openssh

import (
	sshfx "github.com/pkg/sftp/encoding/ssh/filexfer"
)

const extensionStatVFS = "statvfs@openssh.com"

func init() {
	sshfx.RegisterExtendedPacketType(extensionStatVFS, func() sshfx.ExtendedData {
		return new(StatVFSExtendedPacket)
	})
}

// ExtensionStatVFS returns an ExtensionPair suitable to append into an sshfx.InitPacket or sshfx.VersionPacket.
func ExtensionStatVFS() *sshfx.ExtensionPair {
	return &sshfx.ExtensionPair{
		Name: extensionStatVFS,
		Data: "2",
	}
}

// StatVFSExtendedPacket defines the statvfs@openssh.com extend packet.
type StatVFSExtendedPacket struct {
	Path string
}

// MarshalPacket returns ep as a two-part binary encoding of the full extended packet.
func (ep *StatVFSExtendedPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
	p := &sshfx.ExtendedPacket{
		ExtendedRequest: extensionStatVFS,

		Data: ep,
	}
	return p.MarshalPacket(reqid, b)
}

// MarshalInto encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
func (ep *StatVFSExtendedPacket) MarshalInto(buf *sshfx.Buffer) {
	buf.AppendString(ep.Path)
}

// MarshalBinary encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
//
// NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended packet.
func (ep *StatVFSExtendedPacket) MarshalBinary() ([]byte, error) {
	size := 4 + len(ep.Path) // string(path)

	buf := sshfx.NewBuffer(make([]byte, size))

	ep.MarshalInto(buf)

	return buf.Bytes(), nil
}

// UnmarshalFrom decodes the statvfs@openssh.com extended packet-specific data into ep.
func (ep *StatVFSExtendedPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
	if ep.Path, err = buf.ConsumeString(); err != nil {
		return err
	}

	return nil
}

// UnmarshalBinary decodes the statvfs@openssh.com extended packet-specific data into ep.
func (ep *StatVFSExtendedPacket) UnmarshalBinary(data []byte) (err error) {
	return ep.UnmarshalFrom(sshfx.NewBuffer(data))
}

const extensionFStatVFS = "fstatvfs@openssh.com"

func init() {
	sshfx.RegisterExtendedPacketType(extensionFStatVFS, func() sshfx.ExtendedData {
		return new(FStatVFSExtendedPacket)
	})
}

// ExtensionFStatVFS returns an ExtensionPair suitable to append into an sshfx.InitPacket or sshfx.VersionPacket.
func ExtensionFStatVFS() *sshfx.ExtensionPair {
	return &sshfx.ExtensionPair{
		Name: extensionFStatVFS,
		Data: "2",
	}
}

// FStatVFSExtendedPacket defines the fstatvfs@openssh.com extend packet.
type FStatVFSExtendedPacket struct {
	Path string
}

// MarshalPacket returns ep as a two-part binary encoding of the full extended packet.
func (ep *FStatVFSExtendedPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
	p := &sshfx.ExtendedPacket{
		ExtendedRequest: extensionFStatVFS,

		Data: ep,
	}
	return p.MarshalPacket(reqid, b)
}

// MarshalInto encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
func (ep *FStatVFSExtendedPacket) MarshalInto(buf *sshfx.Buffer) {
	buf.AppendString(ep.Path)
}

// MarshalBinary encodes ep into the binary encoding of the statvfs@openssh.com extended packet-specific data.
//
// NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended packet.
func (ep *FStatVFSExtendedPacket) MarshalBinary() ([]byte, error) {
	size := 4 + len(ep.Path) // string(path)

	buf := sshfx.NewBuffer(make([]byte, size))

	ep.MarshalInto(buf)

	return buf.Bytes(), nil
}

// UnmarshalFrom decodes the statvfs@openssh.com extended packet-specific data into ep.
func (ep *FStatVFSExtendedPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
	if ep.Path, err = buf.ConsumeString(); err != nil {
		return err
	}

	return nil
}

// UnmarshalBinary decodes the statvfs@openssh.com extended packet-specific data into ep.
func (ep *FStatVFSExtendedPacket) UnmarshalBinary(data []byte) (err error) {
	return ep.UnmarshalFrom(sshfx.NewBuffer(data))
}

// The values for the MountFlags field.
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL
const (
	MountFlagsReadOnly = 0x1 // SSH_FXE_STATVFS_ST_RDONLY
	MountFlagsNoSUID   = 0x2 // SSH_FXE_STATVFS_ST_NOSUID
)

// StatVFSExtendedReplyPacket defines the extended reply packet for statvfs@openssh.com and fstatvfs@openssh.com requests.
type StatVFSExtendedReplyPacket struct {
	BlockSize     uint64 /* f_bsize:   file system block size */
	FragmentSize  uint64 /* f_frsize:  fundamental fs block size / fagment size */
	Blocks        uint64 /* f_blocks:  number of blocks (unit f_frsize) */
	BlocksFree    uint64 /* f_bfree:   free blocks in filesystem */
	BlocksAvail   uint64 /* f_bavail:  free blocks for non-root */
	Files         uint64 /* f_files:   total file inodes */
	FilesFree     uint64 /* f_ffree:   free file inodes */
	FilesAvail    uint64 /* f_favail:  free file inodes for to non-root */
	FilesystemID  uint64 /* f_fsid:    file system id */
	MountFlags    uint64 /* f_flag:    bit mask of mount flag values */
	MaxNameLength uint64 /* f_namemax: maximum filename length */
}

// MarshalPacket returns ep as a two-part binary encoding of the full extended reply packet.
func (ep *StatVFSExtendedReplyPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) {
	p := &sshfx.ExtendedReplyPacket{
		Data: ep,
	}
	return p.MarshalPacket(reqid, b)
}

// MarshalInto encodes ep into the binary encoding of the (f)statvfs@openssh.com extended reply packet-specific data.
func (ep *StatVFSExtendedReplyPacket) MarshalInto(buf *sshfx.Buffer) {
	buf.AppendUint64(ep.BlockSize)
	buf.AppendUint64(ep.FragmentSize)
	buf.AppendUint64(ep.Blocks)
	buf.AppendUint64(ep.BlocksFree)
	buf.AppendUint64(ep.BlocksAvail)
	buf.AppendUint64(ep.Files)
	buf.AppendUint64(ep.FilesFree)
	buf.AppendUint64(ep.FilesAvail)
	buf.AppendUint64(ep.FilesystemID)
	buf.AppendUint64(ep.MountFlags)
	buf.AppendUint64(ep.MaxNameLength)
}

// MarshalBinary encodes ep into the binary encoding of the (f)statvfs@openssh.com extended reply packet-specific data.
//
// NOTE: This _only_ encodes the packet-specific data, it does not encode the full extended reply packet.
func (ep *StatVFSExtendedReplyPacket) MarshalBinary() ([]byte, error) {
	size := 11 * 8 // 11 × uint64(various)

	b := sshfx.NewBuffer(make([]byte, size))
	ep.MarshalInto(b)
	return b.Bytes(), nil
}

// UnmarshalFrom decodes the fstatvfs@openssh.com extended reply packet-specific data into ep.
func (ep *StatVFSExtendedReplyPacket) UnmarshalFrom(buf *sshfx.Buffer) (err error) {
	if ep.BlockSize, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.FragmentSize, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.Blocks, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.BlocksFree, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.BlocksAvail, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.Files, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.FilesFree, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.FilesAvail, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.FilesystemID, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.MountFlags, err = buf.ConsumeUint64(); err != nil {
		return err
	}
	if ep.MaxNameLength, err = buf.ConsumeUint64(); err != nil {
		return err
	}

	return nil
}

// UnmarshalBinary decodes the fstatvfs@openssh.com extended reply packet-specific data into ep.
func (ep *StatVFSExtendedReplyPacket) UnmarshalBinary(data []byte) (err error) {
	return ep.UnmarshalFrom(sshfx.NewBuffer(data))
}
