// Package sftp implements the SSH File Transfer Protocol as described in
// https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02
package sftp

import (
	"fmt"

	"github.com/pkg/errors"
)

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 errors.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 errors.Errorf("sftp: unimplemented seek whence %d", whence)
}

func unexpectedCount(want, got uint32) error {
	return errors.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{}, errors.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
}
