// 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 main

import (
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"

	"go.fuchsia.dev/fuchsia/tools/sdk-tools/sdkcommon"
)

type testSDKProperties struct {
	err                   error
	expectedTargetAddress string
}

func (testSDK testSDKProperties) RunSSHShell(targetAddress string, sshConfig string,
	privateKey string, sshPort string, verbose bool, sshArgs []string) error {
	if targetAddress == "" {
		return errors.New("target address must be specified")
	}
	if targetAddress != testSDK.expectedTargetAddress {
		return fmt.Errorf("target address %v did not match expected %v", targetAddress, testSDK.expectedTargetAddress)
	}
	return testSDK.err
}

const defaultIPAddress = "e80::c00f:f0f0:eeee:cccc"

func clearEnvVars() {
	os.Unsetenv("_EXPECTED_IPADDR")
	os.Unsetenv("_EXPECTED_PORT")
	os.Unsetenv("_EXPECTED_ARGS")
	os.Unsetenv("_EXPECTED_SSHCONFIG")
	os.Unsetenv("_EXPECTED_PRIVKEY")
	os.Unsetenv("_FAKE_FFX_DEVICE_CONFIG_DATA")
	os.Unsetenv("_FAKE_FFX_DEVICE_CONFIG_DEFAULT_DEVICE")
	os.Unsetenv("_FAKE_FFX_TARGET_DEFAULT")
	os.Unsetenv("_FAKE_FFX_TARGET_LIST")
	os.Unsetenv("_FAKE_FFX_GET_SSH_ADDRESS")
}

func TestMain(t *testing.T) {
	dataDir := t.TempDir()
	savedArgs := os.Args
	savedCommandLine := flag.CommandLine
	sdkcommon.ExecCommand = helperCommandForFSSH
	defer func() {
		clearEnvVars()
		sdkcommon.ExecCommand = exec.Command
		os.Args = savedArgs
		flag.CommandLine = savedCommandLine
	}()

	tests := []struct {
		name                   string
		args                   []string
		deviceConfiguration    string
		defaultConfigDevice    string
		ffxDefaultDevice       string
		ffxTargetList          string
		ffxTargetDefault       string
		ffxTargetGetSSHAddress string
		expectedIPAddress      string
		expectedPort           string
		expectedSSHConfig      string
		expectedPrivateKey     string
		expectedSSHArgs        string
	}{
		{
			name:                   "No configured device but 1 device is discoverable",
			args:                   []string{os.Args[0], "-data-path", dataDir},
			expectedIPAddress:      "::1f",
			expectedPort:           "",
			expectedSSHArgs:        "",
			expectedSSHConfig:      filepath.Join(dataDir, "sshconfig"),
			expectedPrivateKey:     "",
			ffxTargetList:          `[{"nodename":"some-device","rcs_state":"N","serial":"<unknown>","target_type":"Unknown","target_state":"Product","addresses":["::1f"]}]`,
			ffxTargetGetSSHAddress: `[::1f]:22`,
		},
		{
			name:               "Multiple discoverable devices and passing --device-name",
			args:               []string{os.Args[0], "-data-path", dataDir, "-level", "debug", "--device-name", "test-device"},
			expectedIPAddress:  "::1f",
			expectedPort:       "",
			expectedSSHArgs:    "",
			expectedSSHConfig:  filepath.Join(dataDir, "sshconfig"),
			expectedPrivateKey: "",
			ffxTargetList: `[{"nodename":"test-device","rcs_state":"N","serial":"<unknown>","target_type":"Unknown","target_state":"Product","addresses":["::1f"]},
			{"nodename":"random-device","rcs_state":"N","serial":"<unknown>","target_type":"Unknown","target_state":"Product","addresses":["::2f"]}]`,
			ffxTargetGetSSHAddress: `[::1f]:22`,
		},
		{
			name: "fconfig has a default device",
			args: []string{os.Args[0], "-data-path", dataDir},
			deviceConfiguration: `{
			"_DEFAULT_DEVICE_":"remote-target-name",
			"remote-target-name":{
				"bucket":"fuchsia-bucket",
				"device-name":"remote-target-name",
				"image":"release",
				"package-port":"",
				"package-repo":"",
				"default": "true"
			}
			}`,
			ffxTargetGetSSHAddress: `[::1f]:2202`,
			ffxTargetList: `[{"nodename":"remote-target-name","rcs_state":"N","serial":"<unknown>","target_type":"Unknown","target_state":"Product","addresses":["::1f"]},
		{"nodename":"random-device","rcs_state":"N","serial":"<unknown>","target_type":"Unknown","target_state":"Product","addresses":["::2f"]}]`,
			defaultConfigDevice: "\"remote-target-name\"",
			expectedIPAddress:   "::1f",
			expectedPort:        "2202",
			expectedSSHArgs:     "",
			expectedSSHConfig:   filepath.Join(dataDir, "sshconfig"),
			expectedPrivateKey:  "",
		},
		{
			name: "fconfig non-default device with --device-name",
			args: []string{os.Args[0], "-data-path", dataDir, "--device-name", "random-device"},
			deviceConfiguration: `{
			"_DEFAULT_DEVICE_":"remote-target-name",
			"remote-target-name":{
				"bucket":"fuchsia-bucket",
				"device-name":"remote-target-name",
				"image":"release",
				"package-port":"",
				"package-repo":"",
				"default": "true"
			},
			"random-device":{
				"bucket":"fuchsia-bucket",
				"device-name":"test-target-name",
				"image":"release",
				"package-port":"",
				"package-repo":"",
				"default": "false"
			}	
			}`,
			defaultConfigDevice: "\"remote-target-name\"",
			ffxTargetList: `[{"nodename":"remote-target-name","rcs_state":"N","serial":"<unknown>","target_type":"Unknown","target_state":"Product","addresses":["::1f"]},
			{"nodename":"random-device","rcs_state":"N","serial":"<unknown>","target_type":"Unknown","target_state":"Product","addresses":["::2f"]}]`,
			ffxTargetGetSSHAddress: `[::1f]:2202`,
			expectedIPAddress:      "::2f",
			expectedPort:           "8022",
			expectedSSHArgs:        "",
			expectedSSHConfig:      filepath.Join(dataDir, "sshconfig"),
			expectedPrivateKey:     "",
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			clearEnvVars()
			os.Args = test.args
			os.Setenv("_EXPECTED_IPADDR", test.expectedIPAddress)
			os.Setenv("_EXPECTED_PORT", test.expectedPort)
			os.Setenv("_EXPECTED_ARGS", test.expectedSSHArgs)
			os.Setenv("_EXPECTED_SSHCONFIG", test.expectedSSHConfig)
			os.Setenv("_EXPECTED_PRIVKEY", test.expectedPrivateKey)
			os.Setenv("_FAKE_FFX_DEVICE_CONFIG_DATA", test.deviceConfiguration)
			os.Setenv("_FAKE_FFX_DEVICE_CONFIG_DEFAULT_DEVICE", test.defaultConfigDevice)
			os.Setenv("_FAKE_FFX_TARGET_DEFAULT", test.ffxTargetDefault)
			os.Setenv("_FAKE_FFX_TARGET_LIST", test.ffxTargetList)
			os.Setenv("_FAKE_FFX_GET_SSH_ADDRESS", test.ffxTargetGetSSHAddress)
			flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
			osExit = func(code int) {
				if code != 0 {
					t.Fatalf("Non-zero error code %d", code)
				}
			}
			main()
		})
	}
}

func TestSSH(t *testing.T) {
	defaultDeviceProperties := make(map[string]string)
	defaultDeviceProperties[fmt.Sprintf("test-device.%v", sdkcommon.DeviceIPKey)] = defaultIPAddress
	tests := []struct {
		sdk           sdkProvider
		verbose       bool
		targetAddress string
		sshConfig     string
		privateKey    string
		args          []string
		expectedError string
	}{
		{
			sdk:           testSDKProperties{},
			expectedError: "target address must be specified",
		},
		{
			sdk:           testSDKProperties{expectedTargetAddress: defaultIPAddress},
			targetAddress: defaultIPAddress,
			expectedError: "",
		},
		{
			sdk: testSDKProperties{
				expectedTargetAddress: defaultIPAddress,
			},
			targetAddress: defaultIPAddress,
			expectedError: "",
		},
		{
			sdk: testSDKProperties{
				expectedTargetAddress: defaultIPAddress,
			},
			targetAddress: defaultIPAddress,
			verbose:       true,
			expectedError: "",
		},
		{
			sdk: testSDKProperties{
				expectedTargetAddress: defaultIPAddress,
			},
			targetAddress: defaultIPAddress,
			sshConfig:     "custom-config",
			privateKey:    "private-key",
			expectedError: "",
		},
	}

	for _, test := range tests {
		err := ssh(test.sdk, test.verbose, test.targetAddress, test.sshConfig, test.privateKey, "", test.args)
		if err != nil {
			message := fmt.Sprintf("%v", err)
			if message != test.expectedError {
				t.Fatalf("Unexpected error %v does not match %v", message, test.expectedError)
			}
		} else if test.expectedError != "" {
			t.Fatalf("Expected error '%v', but got no error", test.expectedError)
		}
	}
}

// See exec_test.go for details, but effectively this runs the function called TestHelperProcess passing
// the args.
func helperCommandForFSSH(command string, s ...string) (cmd *exec.Cmd) {

	var cs []string
	if strings.HasSuffix(command, "/ffx") {
		cs = []string{"-test.run=TestFakeFFX", "--"}
	} else if strings.HasSuffix(command, "/ssh") {
		cs = []string{"-test.run=TestFakeSSH", "--"}
	} else if strings.HasSuffix(command, "/ssh-keygen") {
		cs = []string{"-test.run=TestFakeKeygen", "--"}
	} else {
		return exec.Command(fmt.Sprintf("unsupported/command/%v", command))
	}

	cs = append(cs, command)
	cs = append(cs, s...)

	cmd = exec.Command(os.Args[0], cs...)
	// Set this in the environment, so we can control the result.
	cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
	return cmd
}

func TestFakeKeygen(t *testing.T) {
	t.Helper()
	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
		return
	}
	defer os.Exit(0)
}
func TestFakeSSH(t *testing.T) {
	t.Helper()
	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
		return
	}
	defer os.Exit(0)
	args := os.Args
	for len(args) > 0 {
		if args[0] == "--" {
			args = args[1:]
			break
		}
		args = args[1:]
	}

	expectedIPAddress := os.Getenv("_EXPECTED_IPADDR")
	expectedPort := os.Getenv("_EXPECTED_PORT")
	expectedSSHArgs := os.Getenv("_EXPECTED_ARGS")
	expectedSSHConfig := os.Getenv("_EXPECTED_SSHCONFIG")
	//expectedPrivateKey := os.Getenv("_EXPECTED_PRIVKEY")
	expectedArgs := []string{
		args[0],
		"-F",
		expectedSSHConfig,
	}
	if expectedPort != "" {
		expectedArgs = append(expectedArgs, "-p", expectedPort)
	}

	expectedArgs = append(expectedArgs, expectedIPAddress)

	expectedArgs = append(expectedArgs, strings.Fields(expectedSSHArgs)...)

	if len(expectedArgs) != len(args) {
		fmt.Fprintf(os.Stderr, "Fake SSH expected %d args, but got %d args.\n", len(expectedArgs), len(args))
		fmt.Fprintf(os.Stderr, "Expected [%v]\nActual   [%v]\n", expectedArgs, args)
		os.Exit(1)
	}
	for i, arg := range args {
		if arg != expectedArgs[i] {
			fmt.Fprintf(os.Stderr, "Expected arg[%d] != actual arg. [%v] != [%v]", i, expectedArgs[i], arg)
			os.Exit(1)
		}
	}
	os.Exit(0)
}

func TestFakeFFX(t *testing.T) {
	t.Helper()

	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
		return
	}
	defer os.Exit(0)

	args := os.Args
	for len(args) > 0 {
		if args[0] == "--" {
			args = args[1:]
			break
		}
		args = args[1:]
	}

	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "No command\n")
		os.Exit(2)
	}
	if strings.HasSuffix(args[0], "ffx") && args[1] == "config" && args[2] == "env" {
		if len(args) == 3 {
			fmt.Printf("Welcome to ffx doctor.")
			fmt.Printf("Environment:\n")
			fmt.Printf("User: none\n")
			fmt.Printf("Build: none\n")
			fmt.Printf("Global: none\n")
			os.Exit(0)
		} else if args[3] == "set" {
			os.Exit(0)
		}
	} else if strings.HasSuffix(args[0], "ffx") && args[1] == "config" && args[2] == "get" {
		if len(args) > 3 {
			if args[3] == "DeviceConfiguration" {
				fmt.Printf(os.Getenv("_FAKE_FFX_DEVICE_CONFIG_DATA"))
				os.Exit(0)
			} else if args[3] == "DeviceConfiguration._DEFAULT_DEVICE_" {
				fmt.Printf(os.Getenv("_FAKE_FFX_DEVICE_CONFIG_DEFAULT_DEVICE"))
				os.Exit(0)
			}

		}
	} else if strings.HasSuffix(args[0], "ffx") && args[1] == "target" && args[2] == "default" && args[3] == "get" {
		fmt.Printf("%v\n", os.Getenv("_FAKE_FFX_TARGET_DEFAULT"))
		os.Exit(0)
	} else if strings.HasSuffix(args[0], "ffx") && args[1] == "target" && args[2] == "list" && args[3] == "--format" && args[4] == "json" {
		fmt.Printf("%v\n", os.Getenv("_FAKE_FFX_TARGET_LIST"))
		os.Exit(0)
	} else if strings.HasSuffix(args[0], "ffx") && args[3] == "target" && args[4] == "get-ssh-address" {
		if args[2] == "random-device" {
			fmt.Printf("[::2f]:8022\n")
			os.Exit(0)
		}
		fmt.Printf("%v\n", os.Getenv("_FAKE_FFX_GET_SSH_ADDRESS"))
		os.Exit(0)
	}

	fmt.Fprintf(os.Stderr, "Unknown command not supported in faking ffx %v", os.Args)
	os.Exit(2)

}
