// Package sftp implements the SSH File Transfer Protocol as described in
// https://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt
package sftp

import (
	"fmt"
)

const (
	sshFxpInit          = 1
	sshFxpVersion       = 2
	sshFxpOpen          = 3
	sshFxpClose         = 4
	sshFxpRead          = 5
	sshFxpWrite         = 6
	sshFxpLstat         = 7
	sshFxpFstat         = 8
	sshFxpSetstat       = 9
	sshFxpFsetstat      = 10
	sshFxpOpendir       = 11
	sshFxpReaddir       = 12
	sshFxpRemove        = 13
	sshFxpMkdir         = 14
	sshFxpRmdir         = 15
	sshFxpRealpath      = 16
	sshFxpStat          = 17
	sshFxpRename        = 18
	sshFxpReadlink      = 19
	sshFxpSymlink       = 20
	sshFxpStatus        = 101
	sshFxpHandle        = 102
	sshFxpData          = 103
	sshFxpName          = 104
	sshFxpAttrs         = 105
	sshFxpExtended      = 200
	sshFxpExtendedReply = 201
)

const (
	sshFxOk               = 0
	sshFxEOF              = 1
	sshFxNoSuchFile       = 2
	sshFxPermissionDenied = 3
	sshFxFailure          = 4
	sshFxBadMessage       = 5
	sshFxNoConnection     = 6
	sshFxConnectionLost   = 7
	sshFxOPUnsupported    = 8

	// see draft-ietf-secsh-filexfer-13
	// https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1
	sshFxInvalidHandle           = 9
	sshFxNoSuchPath              = 10
	sshFxFileAlreadyExists       = 11
	sshFxWriteProtect            = 12
	sshFxNoMedia                 = 13
	sshFxNoSpaceOnFilesystem     = 14
	sshFxQuotaExceeded           = 15
	sshFxUnknownPrincipal        = 16
	sshFxLockConflict            = 17
	sshFxDirNotEmpty             = 18
	sshFxNotADirectory           = 19
	sshFxInvalidFilename         = 20
	sshFxLinkLoop                = 21
	sshFxCannotDelete            = 22
	sshFxInvalidParameter        = 23
	sshFxFileIsADirectory        = 24
	sshFxByteRangeLockConflict   = 25
	sshFxByteRangeLockRefused    = 26
	sshFxDeletePending           = 27
	sshFxFileCorrupt             = 28
	sshFxOwnerInvalid            = 29
	sshFxGroupInvalid            = 30
	sshFxNoMatchingByteRangeLock = 31
)

const (
	sshFxfRead   = 0x00000001
	sshFxfWrite  = 0x00000002
	sshFxfAppend = 0x00000004
	sshFxfCreat  = 0x00000008
	sshFxfTrunc  = 0x00000010
	sshFxfExcl   = 0x00000020
)

var (
	// supportedSFTPExtensions defines the supported extensions
	supportedSFTPExtensions = []sshExtensionPair{
		{"hardlink@openssh.com", "1"},
		{"posix-rename@openssh.com", "1"},
		{"statvfs@openssh.com", "2"},
	}
	sftpExtensions = supportedSFTPExtensions
)

type fxp uint8

func (f fxp) String() string {
	switch f {
	case sshFxpInit:
		return "SSH_FXP_INIT"
	case sshFxpVersion:
		return "SSH_FXP_VERSION"
	case sshFxpOpen:
		return "SSH_FXP_OPEN"
	case sshFxpClose:
		return "SSH_FXP_CLOSE"
	case sshFxpRead:
		return "SSH_FXP_READ"
	case sshFxpWrite:
		return "SSH_FXP_WRITE"
	case sshFxpLstat:
		return "SSH_FXP_LSTAT"
	case sshFxpFstat:
		return "SSH_FXP_FSTAT"
	case sshFxpSetstat:
		return "SSH_FXP_SETSTAT"
	case sshFxpFsetstat:
		return "SSH_FXP_FSETSTAT"
	case sshFxpOpendir:
		return "SSH_FXP_OPENDIR"
	case sshFxpReaddir:
		return "SSH_FXP_READDIR"
	case sshFxpRemove:
		return "SSH_FXP_REMOVE"
	case sshFxpMkdir:
		return "SSH_FXP_MKDIR"
	case sshFxpRmdir:
		return "SSH_FXP_RMDIR"
	case sshFxpRealpath:
		return "SSH_FXP_REALPATH"
	case sshFxpStat:
		return "SSH_FXP_STAT"
	case sshFxpRename:
		return "SSH_FXP_RENAME"
	case sshFxpReadlink:
		return "SSH_FXP_READLINK"
	case sshFxpSymlink:
		return "SSH_FXP_SYMLINK"
	case sshFxpStatus:
		return "SSH_FXP_STATUS"
	case sshFxpHandle:
		return "SSH_FXP_HANDLE"
	case sshFxpData:
		return "SSH_FXP_DATA"
	case sshFxpName:
		return "SSH_FXP_NAME"
	case sshFxpAttrs:
		return "SSH_FXP_ATTRS"
	case sshFxpExtended:
		return "SSH_FXP_EXTENDED"
	case sshFxpExtendedReply:
		return "SSH_FXP_EXTENDED_REPLY"
	default:
		return "unknown"
	}
}

type fx uint8

func (f fx) String() string {
	switch f {
	case sshFxOk:
		return "SSH_FX_OK"
	case sshFxEOF:
		return "SSH_FX_EOF"
	case sshFxNoSuchFile:
		return "SSH_FX_NO_SUCH_FILE"
	case sshFxPermissionDenied:
		return "SSH_FX_PERMISSION_DENIED"
	case sshFxFailure:
		return "SSH_FX_FAILURE"
	case sshFxBadMessage:
		return "SSH_FX_BAD_MESSAGE"
	case sshFxNoConnection:
		return "SSH_FX_NO_CONNECTION"
	case sshFxConnectionLost:
		return "SSH_FX_CONNECTION_LOST"
	case sshFxOPUnsupported:
		return "SSH_FX_OP_UNSUPPORTED"
	default:
		return "unknown"
	}
}

type unexpectedPacketErr struct {
	want, got uint8
}

func (u *unexpectedPacketErr) Error() string {
	return fmt.Sprintf("sftp: unexpected packet: want %v, got %v", fxp(u.want), fxp(u.got))
}

func unimplementedPacketErr(u uint8) error {
	return fmt.Errorf("sftp: unimplemented packet type: got %v", fxp(u))
}

type unexpectedIDErr struct{ want, got uint32 }

func (u *unexpectedIDErr) Error() string {
	return fmt.Sprintf("sftp: unexpected id: want %d, got %d", u.want, u.got)
}

func unimplementedSeekWhence(whence int) error {
	return fmt.Errorf("sftp: unimplemented seek whence %d", whence)
}

func unexpectedCount(want, got uint32) error {
	return fmt.Errorf("sftp: unexpected count: want %d, got %d", want, got)
}

type unexpectedVersionErr struct{ want, got uint32 }

func (u *unexpectedVersionErr) Error() string {
	return fmt.Sprintf("sftp: unexpected server version: want %v, got %v", u.want, u.got)
}

// A StatusError is returned when an SFTP operation fails, and provides
// additional information about the failure.
type StatusError struct {
	Code      uint32
	msg, lang string
}

func (s *StatusError) Error() string {
	return fmt.Sprintf("sftp: %q (%v)", s.msg, fx(s.Code))
}

// FxCode returns the error code typed to match against the exported codes
func (s *StatusError) FxCode() fxerr {
	return fxerr(s.Code)
}

func getSupportedExtensionByName(extensionName string) (sshExtensionPair, error) {
	for _, supportedExtension := range supportedSFTPExtensions {
		if supportedExtension.Name == extensionName {
			return supportedExtension, nil
		}
	}
	return sshExtensionPair{}, fmt.Errorf("unsupported extension: %s", extensionName)
}

// SetSFTPExtensions allows to customize the supported server extensions.
// See the variable supportedSFTPExtensions for supported extensions.
// This method accepts a slice of sshExtensionPair names for example 'hardlink@openssh.com'.
// If an invalid extension is given an error will be returned and nothing will be changed
func SetSFTPExtensions(extensions ...string) error {
	tempExtensions := []sshExtensionPair{}
	for _, extension := range extensions {
		sftpExtension, err := getSupportedExtensionByName(extension)
		if err != nil {
			return err
		}
		tempExtensions = append(tempExtensions, sftpExtension)
	}
	sftpExtensions = tempExtensions
	return nil
}
