package sftp

import (
	"sync"

	"github.com/stretchr/testify/assert"

	"bytes"
	"errors"
	"io"
	"os"
	"testing"
)

type testHandler struct {
	filecontents []byte      // dummy contents
	output       io.WriterAt // dummy file out
	err          error       // dummy error, should be file related
}

func (t *testHandler) Fileread(r *Request) (io.ReaderAt, error) {
	if t.err != nil {
		return nil, t.err
	}
	_ = r.WithContext(r.Context()) // initialize context for deadlock testing
	return bytes.NewReader(t.filecontents), nil
}

func (t *testHandler) Filewrite(r *Request) (io.WriterAt, error) {
	if t.err != nil {
		return nil, t.err
	}
	_ = r.WithContext(r.Context()) // initialize context for deadlock testing
	return io.WriterAt(t.output), nil
}

func (t *testHandler) Filecmd(r *Request) error {
	_ = r.WithContext(r.Context()) // initialize context for deadlock testing
	return t.err
}

func (t *testHandler) Filelist(r *Request) (ListerAt, error) {
	if t.err != nil {
		return nil, t.err
	}
	_ = r.WithContext(r.Context()) // initialize context for deadlock testing
	f, err := os.Open(r.Filepath)
	if err != nil {
		return nil, err
	}
	fi, err := f.Stat()
	if err != nil {
		return nil, err
	}
	return listerat([]os.FileInfo{fi}), nil
}

// make sure len(fakefile) == len(filecontents)
type fakefile [10]byte

var filecontents = []byte("file-data.")

// XXX need new for creating test requests that supports Open-ing
func testRequest(method string) *Request {
	var flags uint32
	switch method {
	case "Get":
		flags = flags | sshFxfRead
	case "Put":
		flags = flags | sshFxfWrite
	}
	request := &Request{
		Filepath: "./request_test.go",
		Method:   method,
		Attrs:    []byte("foo"),
		Flags:    flags,
		Target:   "foo",
		state:    state{RWMutex: new(sync.RWMutex)},
	}
	return request
}

func (ff *fakefile) WriteAt(p []byte, off int64) (int, error) {
	n := copy(ff[off:], p)
	return n, nil
}

func (ff fakefile) string() string {
	b := make([]byte, len(ff))
	copy(b, ff[:])
	return string(b)
}

func newTestHandlers() Handlers {
	handler := &testHandler{
		filecontents: filecontents,
		output:       &fakefile{},
		err:          nil,
	}
	return Handlers{
		FileGet:  handler,
		FilePut:  handler,
		FileCmd:  handler,
		FileList: handler,
	}
}

func (h Handlers) getOutString() string {
	handler := h.FilePut.(*testHandler)
	return handler.output.(*fakefile).string()
}

var errTest = errors.New("test error")

func (h *Handlers) returnError(err error) {
	handler := h.FilePut.(*testHandler)
	handler.err = err
}

func getStatusMsg(p interface{}) string {
	pkt := p.(sshFxpStatusPacket)
	return pkt.StatusError.msg
}
func checkOkStatus(t *testing.T, p interface{}) {
	pkt := p.(sshFxpStatusPacket)
	assert.Equal(t, pkt.StatusError.Code, uint32(sshFxOk),
		"sshFxpStatusPacket not OK\n", pkt.StatusError.msg)
}

// fake/test packet
type fakePacket struct {
	myid   uint32
	handle string
}

func (f fakePacket) id() uint32 {
	return f.myid
}

func (f fakePacket) getHandle() string {
	return f.handle
}
func (fakePacket) UnmarshalBinary(d []byte) error { return nil }

// XXX can't just set method to Get, need to use Open to setup Get/Put
func TestRequestGet(t *testing.T) {
	handlers := newTestHandlers()
	request := testRequest("Get")
	pkt := fakePacket{myid: 1}
	request.open(handlers, pkt)
	// req.length is 5, so we test reads in 5 byte chunks
	for i, txt := range []string{"file-", "data."} {
		pkt := &sshFxpReadPacket{ID: uint32(i), Handle: "a",
			Offset: uint64(i * 5), Len: 5}
		rpkt := request.call(handlers, pkt, nil, 0)
		dpkt := rpkt.(*sshFxpDataPacket)
		assert.Equal(t, dpkt.id(), uint32(i))
		assert.Equal(t, string(dpkt.Data), txt)
	}
}

func TestRequestCustomError(t *testing.T) {
	handlers := newTestHandlers()
	request := testRequest("Stat")
	pkt := fakePacket{myid: 1}
	cmdErr := errors.New("stat not supported")
	handlers.returnError(cmdErr)
	rpkt := request.call(handlers, pkt, nil, 0)
	assert.Equal(t, rpkt, statusFromError(rpkt, cmdErr))
}

// XXX can't just set method to Get, need to use Open to setup Get/Put
func TestRequestPut(t *testing.T) {
	handlers := newTestHandlers()
	request := testRequest("Put")
	request.state.writerAt, _ = handlers.FilePut.Filewrite(request)
	pkt := &sshFxpWritePacket{ID: 0, Handle: "a", Offset: 0, Length: 5,
		Data: []byte("file-")}
	rpkt := request.call(handlers, pkt, nil, 0)
	checkOkStatus(t, rpkt)
	pkt = &sshFxpWritePacket{ID: 1, Handle: "a", Offset: 5, Length: 5,
		Data: []byte("data.")}
	rpkt = request.call(handlers, pkt, nil, 0)
	checkOkStatus(t, rpkt)
	assert.Equal(t, "file-data.", handlers.getOutString())
}

func TestRequestCmdr(t *testing.T) {
	handlers := newTestHandlers()
	request := testRequest("Mkdir")
	pkt := fakePacket{myid: 1}
	rpkt := request.call(handlers, pkt, nil, 0)
	checkOkStatus(t, rpkt)

	handlers.returnError(errTest)
	rpkt = request.call(handlers, pkt, nil, 0)
	assert.Equal(t, rpkt, statusFromError(rpkt, errTest))
}

func TestRequestInfoStat(t *testing.T) {
	handlers := newTestHandlers()
	request := testRequest("Stat")
	pkt := fakePacket{myid: 1}
	rpkt := request.call(handlers, pkt, nil, 0)
	spkt, ok := rpkt.(*sshFxpStatResponse)
	assert.True(t, ok)
	assert.Equal(t, spkt.info.Name(), "request_test.go")
}

func TestRequestInfoList(t *testing.T) {
	handlers := newTestHandlers()
	request := testRequest("List")
	request.handle = "1"
	pkt := fakePacket{myid: 1}
	rpkt := request.opendir(handlers, pkt)
	hpkt, ok := rpkt.(*sshFxpHandlePacket)
	if assert.True(t, ok) {
		assert.Equal(t, hpkt.Handle, "1")
	}
	pkt = fakePacket{myid: 2}
	request.call(handlers, pkt, nil, 0)
}
func TestRequestInfoReadlink(t *testing.T) {
	handlers := newTestHandlers()
	request := testRequest("Readlink")
	pkt := fakePacket{myid: 1}
	rpkt := request.call(handlers, pkt, nil, 0)
	npkt, ok := rpkt.(*sshFxpNamePacket)
	if assert.True(t, ok) {
		assert.IsType(t, sshFxpNameAttr{}, npkt.NameAttrs[0])
		assert.Equal(t, npkt.NameAttrs[0].Name, "request_test.go")
	}
}

func TestOpendirHandleReuse(t *testing.T) {
	handlers := newTestHandlers()
	request := testRequest("Stat")
	request.handle = "1"
	pkt := fakePacket{myid: 1}
	rpkt := request.call(handlers, pkt, nil, 0)
	assert.IsType(t, &sshFxpStatResponse{}, rpkt)

	request.Method = "List"
	pkt = fakePacket{myid: 2}
	rpkt = request.opendir(handlers, pkt)
	if assert.IsType(t, &sshFxpHandlePacket{}, rpkt) {
		hpkt := rpkt.(*sshFxpHandlePacket)
		assert.Equal(t, hpkt.Handle, "1")
	}
	rpkt = request.call(handlers, pkt, nil, 0)
	assert.IsType(t, &sshFxpNamePacket{}, rpkt)
}
