// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package fuzz

import (
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
	"testing"

	"github.com/golang/glog"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
)

// These SSHConnector tests connect to an in-memory SSH server (see ssh_mock.go
// for details), so we have good coverage of the SSH/SFTP mechanics. However,
// on the remote side, they rely on mocked commands and a mocked filesystem so
// do not test interaction with an actual instance.  For that, we rely on the
// end-to-end tests in e2e_test.go.

func TestSSHConnectorHandle(t *testing.T) {
	c := &SSHConnector{Host: "somehost", Port: 123, Key: "keyfile"}

	handle, err := NewHandleFromObjects(c)
	if err != nil {
		t.Fatalf("error creating handle: %s", err)
	}

	// Note: we don't serialize here because that is covered by handle tests
	reloadedConn, err := loadConnectorFromHandle(handle)
	if err != nil {
		t.Fatalf("error loading connector from handle: %s", err)
	}

	c2, ok := reloadedConn.(*SSHConnector)
	if !ok {
		t.Fatalf("incorrect connector type")
	}

	if diff := cmp.Diff(c, c2, cmpopts.IgnoreUnexported(SSHConnector{})); diff != "" {
		t.Fatalf("incorrect data in reloaded connector (-want +got):\n%s", diff)
	}
}

func TestSSHCommand(t *testing.T) {
	c, _ := getFakeSSHConnector(t)
	defer c.Close()

	arg := "some cool args"
	cmd := c.Command("echo", arg)
	out, err := cmd.Output()
	if err != nil {
		t.Fatalf("error running remote command: %s", err)
	}

	if string(out) != arg+"\n" {
		t.Fatalf("unexpected output: %q", string(out))
	}
}

func TestSSHInvalidCommand(t *testing.T) {
	c, _ := getFakeSSHConnector(t)
	defer c.Close()

	cmd := c.Command("LOAD", `"*",8`)
	if err := cmd.Run(); err == nil || err.(*InstanceCmdError).ReturnCode != 127 {
		t.Fatalf("expected command not found but got: %s", err)
	}
}

func TestSSHGet(t *testing.T) {
	c, fs := getFakeSSHConnector(t)
	defer c.Close()

	tmpDir := getTempdir(t)
	defer os.RemoveAll(tmpDir)

	testFile := &fakeFile{name: "/testfile", content: "test file contents"}
	fs.files = append(fs.files, testFile)

	if err := c.Get("/testfile", tmpDir); err != nil {
		t.Fatalf("error getting file: %s", err)
	}

	got, err := ioutil.ReadFile(path.Join(tmpDir, testFile.name))
	if err != nil {
		t.Fatalf("error reading fetched file: %s", err)
	}

	if diff := cmp.Diff(testFile.content, string(got)); diff != "" {
		t.Fatalf("fetched file has unexpected content (-want +got):\n%s", diff)
	}
}

func TestSSHGetNonexistentSourceFile(t *testing.T) {
	c, _ := getFakeSSHConnector(t)
	defer c.Close()

	tmpDir := getTempdir(t)
	defer os.RemoveAll(tmpDir)

	if err := c.Get("/testfile", tmpDir); err == nil {
		t.Fatal("expected error but succeeded")
	}
}

func TestSSHGetToNonexistentDestDir(t *testing.T) {
	c, _ := getFakeSSHConnector(t)
	defer c.Close()

	tmpDir := getTempdir(t)
	defer os.RemoveAll(tmpDir)

	if err := c.Get("/testfile", filepath.Join(tmpDir, "nope")); err == nil {
		t.Fatal("expected error but succeeded")
	}
}

func TestSSHPut(t *testing.T) {
	c, fs := getFakeSSHConnector(t)
	defer c.Close()

	tmpDir := getTempdir(t)
	defer os.RemoveAll(tmpDir)

	tmpFile := path.Join(tmpDir, "testfile")
	fileContents := "test file contents"

	if err := ioutil.WriteFile(tmpFile, []byte(fileContents), 0o600); err != nil {
		t.Fatalf("error writing local file: %s", err)
	}

	remotePath := "/some/dir"
	fs.files = []*fakeFile{{name: remotePath, isDir: true}}

	if err := c.Put(tmpFile, remotePath); err != nil {
		t.Fatalf("error putting file: %s", err)
	}

	expectRemoteFileWithContent(t, fs, path.Join(remotePath, filepath.Base(tmpFile)), fileContents)
}

func TestSSHGetGlob(t *testing.T) {
	c, fs := getFakeSSHConnector(t)
	defer c.Close()

	tmpDir := getTempdir(t)
	defer os.RemoveAll(tmpDir)

	testFiles := []*fakeFile{
		{name: "/subdir/a", content: "apple"},
		{name: "/subdir/b", content: "banana"},
		{name: "/subdir/j", content: "jabuticaba"},
	}

	// Add a fake directory entry so globbing works correctly
	fs.files = append(testFiles, &fakeFile{name: "/subdir", isDir: true})

	if err := c.Get("/subdir/*", tmpDir); err != nil {
		t.Fatalf("error running remote command: %s", err)
	}

	for _, testFile := range testFiles {
		got, err := ioutil.ReadFile(path.Join(tmpDir, filepath.Base(testFile.name)))
		if err != nil {
			t.Fatalf("error reading fetched file: %s", err)
		}

		if diff := cmp.Diff(testFile.content, string(got)); diff != "" {
			t.Fatalf("fetched file has unexpected content (-want +got):\n%s", diff)
		}
	}
}

func TestSSHPutGlob(t *testing.T) {
	c, fs := getFakeSSHConnector(t)
	defer c.Close()

	tmpDir := getTempdir(t)
	defer os.RemoveAll(tmpDir)

	testFiles := []*fakeFile{
		{name: "a", content: "apple"},
		{name: "b", content: "banana"},
		{name: "j", content: "jabuticaba"},
	}

	for _, testFile := range testFiles {
		tmpFile := path.Join(tmpDir, testFile.name)
		if err := ioutil.WriteFile(tmpFile, []byte(testFile.content), 0o600); err != nil {
			t.Fatalf("error writing local file: %s", err)
		}
	}

	remotePath := "/some/dir"
	fs.files = []*fakeFile{{name: remotePath, isDir: true}}

	if err := c.Put(path.Join(tmpDir, "*"), remotePath); err != nil {
		t.Fatalf("error putting file: %s", err)
	}

	for _, testFile := range testFiles {
		expectRemoteFileWithContent(t, fs, path.Join(remotePath, testFile.name), testFile.content)
	}
}

func TestSSHGetDir(t *testing.T) {
	c, fs := getFakeSSHConnector(t)
	defer c.Close()

	// Set up remote file structure

	testFiles := []*fakeFile{
		{name: "/x/outer/a", content: "apple"},
		{name: "/x/outer/inner/b", content: "banana"},
		{name: "/x/outer/inner/j", content: "jabuticaba"},
	}

	testDirs := []*fakeFile{
		{name: "/x", isDir: true},
		{name: "/x/outer", isDir: true},
		{name: "/x/outer/inner", isDir: true},
	}

	fs.files = append(testFiles, testDirs...)

	// Get /outer (contains file and subdirectory)

	tmpDir := getTempdir(t)
	defer os.RemoveAll(tmpDir)

	srcDir := "/x/outer"
	if err := c.Get(srcDir, tmpDir); err != nil {
		t.Fatalf("error getting dir: %s", err)
	}

	for _, testFile := range testFiles {
		relPath := strings.TrimPrefix(testFile.name, path.Dir(srcDir))
		got, err := ioutil.ReadFile(path.Join(tmpDir, relPath))
		if err != nil {
			t.Fatalf("error reading fetched file: %s", err)
		}

		if diff := cmp.Diff(testFile.content, string(got)); diff != "" {
			t.Fatalf("fetched file has unexpected content (-want +got):\n%s", diff)
		}
	}

	// Get /outer/inner (contains files)

	tmpDir = getTempdir(t)
	defer os.RemoveAll(tmpDir)

	srcDir = "/x/outer/inner"
	if err := c.Get(srcDir, tmpDir); err != nil {
		t.Fatalf("error getting dir: %s", err)
	}

	for _, testFile := range testFiles {
		relName := strings.TrimPrefix(testFile.name, path.Dir(srcDir))
		got, err := ioutil.ReadFile(path.Join(tmpDir, relName))

		if !strings.HasPrefix(testFile.name, srcDir) {
			if err == nil {
				t.Fatalf("unexpected file retrieved: %q", testFile.name)
			}
		} else {
			if err != nil {
				t.Fatalf("error reading fetched file: %s", err)
			}

			if diff := cmp.Diff(testFile.content, string(got)); diff != "" {
				t.Fatalf("fetched file has unexpected content (-want +got):\n%s", diff)
			}
		}
	}
}

func TestSSHPutDir(t *testing.T) {
	tmpDir := getTempdir(t)
	defer os.RemoveAll(tmpDir)

	testFiles := []*fakeFile{
		{name: "/outer/a", content: "apple"},
		{name: "/outer/inner/b", content: "banana"},
		{name: "/outer/inner/j", content: "jabuticaba"},
	}

	testDirs := []*fakeFile{
		{name: "/outer", isDir: true},
		{name: "/outer/inner", isDir: true},
	}

	for _, testDir := range testDirs {
		newDir := path.Join(tmpDir, testDir.name)
		if err := os.Mkdir(newDir, 0o700); err != nil {
			t.Fatalf("error creating local dir: %s", err)
		}
	}

	for _, testFile := range testFiles {
		tmpFile := path.Join(tmpDir, testFile.name)
		if err := ioutil.WriteFile(tmpFile, []byte(testFile.content), 0o600); err != nil {
			t.Fatalf("error writing local file: %s", err)
		}
	}

	// Put /outer (contains file and subdirectory)

	c, fs := getFakeSSHConnector(t)
	defer c.Close()

	remotePath := "/some/dir"
	fs.files = []*fakeFile{{name: remotePath, isDir: true}}

	if err := c.Put(path.Join(tmpDir, "outer"), remotePath); err != nil {
		t.Fatalf("error putting dir: %s", err)
	}

	for _, testFile := range testFiles {
		expectRemoteFileWithContent(t, fs, path.Join(remotePath, testFile.name), testFile.content)
	}

	// Put /outer/inner (contains files)

	c, fs = getFakeSSHConnector(t)
	defer c.Close()

	fs.files = []*fakeFile{{name: remotePath, isDir: true}}

	srcDir := "/outer/inner"
	if err := c.Put(path.Join(tmpDir, srcDir), remotePath); err != nil {
		t.Fatalf("error putting dir: %s", err)
	}

	for _, testFile := range testFiles {
		relName := strings.TrimPrefix(testFile.name, path.Dir(srcDir))
		remotePath := path.Join(remotePath, relName)

		if strings.HasPrefix(testFile.name, srcDir) {
			expectRemoteFileWithContent(t, fs, remotePath, testFile.content)
		} else {
			if _, err := fs.getFile(remotePath); err == nil {
				t.Fatalf("unexpected remote file created: %q", remotePath)
			}
		}
	}
}

// Helper functions:

func getFakeSSHConnector(t *testing.T) (*SSHConnector, *fakeSftp) {
	glog.Info("Starting local SSH server...")

	conn, errCh, fakeFs, err := startLocalSSHServer()
	if err != nil {
		t.Fatalf("error starting local server: %s", err)
	}

	// Monitor for server errors
	go func() {
		for err := range errCh {
			t.Errorf("error from local SSH server: %s", err)
		}
	}()

	return conn, fakeFs
}

func expectRemoteFileWithContent(t *testing.T, fs *fakeSftp, name string, content string) {
	for _, f := range fs.files {
		if f.name == name {
			if diff := cmp.Diff(content, f.content); diff != "" {
				t.Fatalf("uploaded file has unexpected content (-want +got):\n%s", diff)
			}
			return
		}
	}
	t.Fatalf("uploaded file not found in expected location")
}
