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

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strings"
	"time"

	"go.fuchsia.dev/fuchsia/tools/lib/color"
	"go.fuchsia.dev/fuchsia/tools/lib/logger"
)

var (
	// ExecCommand exports exec.Command as a variable so it can be mocked.
	ExecCommand = exec.Command
	// ExecLookPath exported to support mocking.
	ExecLookPath = exec.LookPath
	// logging support.
	logLevel = logger.InfoLevel
	log      = logger.NewLogger(logLevel, color.NewColor(color.ColorAuto), os.Stdout, os.Stderr, "sdk ")
)

// FuchsiaDevice represent a Fuchsia device.
type FuchsiaDevice struct {
	// SSH address of the Fuchsia device.
	SSHAddr string
	// Nodename of the Fuchsia device.
	Name string
}

// deviceInfo represents targets that the ffx daemon currently has in memory.
type deviceInfo struct {
	Nodename    string   `json:"nodename"`
	RCSState    string   `json:"rcs_state"`
	Serial      string   `json:"serial"`
	TargetType  string   `json:"target_type"`
	TargetState string   `json:"target_state"`
	Addresses   []string `json:"addresses"`
}

// GCSImage is used to return the bucket, name and version of a prebuilt.
type GCSImage struct {
	Bucket  string
	Name    string
	Version string
}

// Property keys used to get and set device configuration
const (
	DeviceNameKey  string = "device-name"
	BucketKey      string = "bucket"
	ImageKey       string = "image"
	DeviceIPKey    string = "device-ip"
	SSHPortKey     string = "ssh-port"
	PackageRepoKey string = "package-repo"
	PackagePortKey string = "package-port"
	DefaultKey     string = "default"
	// Top level key used to store device configurations in user level.
	deviceConfigurationKey string = "device_config"
	// Deprecated - top level key for storing device configurations in global level.
	globalDeviceConfigurationKey string = "DeviceConfiguration"
	// Deprecated - key used to identify the default device in global level.
	defaultDeviceKey string = "_DEFAULT_DEVICE_"

	FFXIsolatedEnvKey = "FFX_ISOLATED_CONFIG"

	sleepTimeInSeconds = 5
	UnknownTargetName  = "unknown"
	maxRetryCount      = 3
)

const (
	defaultBucketName  string = "fuchsia"
	DefaultSSHPort     string = "22"
	defaultPackagePort string = "8083"
	helpfulTipMsg      string = `Try running 'ffx target list' and then 'ffx config set device_config.<device-name>.image <image_name>'.
	If you have more than one device listed, use 'ffx target default set <device-name>' to set a default device.`
)

var validPropertyNames = [...]string{
	DeviceNameKey,
	BucketKey,
	ImageKey,
	DeviceIPKey,
	SSHPortKey,
	PackageRepoKey,
	PackagePortKey,
	DefaultKey,
}

// DeviceConfig holds all the properties that are configured
// for a given device.
type DeviceConfig struct {
	DeviceName   string `json:"device-name"`
	Bucket       string `json:"bucket"`
	Image        string `json:"image"`
	DeviceIP     string `json:"device-ip"`
	SSHPort      string `json:"ssh-port"`
	PackageRepo  string `json:"package-repo"`
	PackagePort  string `json:"package-port"`
	IsDefault    bool   `json:"default"`
	Discoverable bool   `json:"discoverable"`
}

// SDKProperties holds the common data for SDK tools.
// These values should be set or initialized by calling
// New().
type SDKProperties struct {
	dataPath string
	version  string
}

func (sdk SDKProperties) setDeviceDefaults(deviceConfig *DeviceConfig) DeviceConfig {
	// no reasonable default for device-name
	if deviceConfig.Bucket == "" {
		deviceConfig.Bucket = defaultBucketName
	}
	// no reasonable default for image
	// no reasonable default for device-ip
	if deviceConfig.SSHPort == "" {
		deviceConfig.SSHPort = DefaultSSHPort
	}
	if deviceConfig.PackageRepo == "" {
		deviceConfig.PackageRepo = sdk.getDefaultPackageRepoDir(deviceConfig.DeviceName)
	}
	if deviceConfig.PackagePort == "" {
		deviceConfig.PackagePort = defaultPackagePort
	}
	return *deviceConfig
}

// Builds the data key for the given segments.
func getDeviceDataKey(segments []string, isGlobal bool) string {
	fullKey := []string{deviceConfigurationKey}
	if isGlobal {
		fullKey = []string{globalDeviceConfigurationKey}
	}
	return strings.Join(append(fullKey, segments...), ".")
}

// DefaultGetUserHomeDir is the default implementation of GetUserHomeDir()
// to allow mocking of user.Current()
func DefaultGetUserHomeDir() (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", nil
	}
	return usr.HomeDir, nil
}

// DefaultGetUsername is the default implementation of GetUsername()
// to allow mocking of user.Current()
func DefaultGetUsername() (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", nil
	}
	return usr.Username, nil
}

// DefaultGetHostname is the default implementation of GetHostname()
// to allow mocking of user.Current()
func DefaultGetHostname() (string, error) {
	return os.Hostname()
}

var (
	// GetUserHomeDir to allow mocking.
	GetUserHomeDir = DefaultGetUserHomeDir

	// GetUsername to allow mocking.
	GetUsername = DefaultGetUsername

	// GetHostname to allow mocking.
	GetHostname = DefaultGetHostname
)

func NewWithDataPath(dataPath string) (SDKProperties, error) {
	sdk := SDKProperties{}

	if dataPath != "" {
		sdk.dataPath = dataPath
	} else {
		homeDir, err := GetUserHomeDir()
		if err != nil {
			return sdk, err
		}
		sdk.dataPath = filepath.Join(homeDir, ".fuchsia")
		if !FileExists(sdk.dataPath) {
			if err := os.MkdirAll(sdk.dataPath, os.ModePerm); err != nil {
				return sdk, err
			}
		}
	}

	toolsDir, err := sdk.GetToolsDir()
	if err != nil {
		return sdk, err
	}
	manifestFile, err := filepath.Abs(filepath.Join(toolsDir, "..", "..", "meta", "manifest.json"))
	if err != nil {
		return sdk, err
	}
	// If this is running in-tree, the manifest may not exist.
	if FileExists(manifestFile) {
		if sdk.version, err = readSDKVersion(manifestFile); err != nil {
			return sdk, err
		}
	}

	return sdk, err
}

// New creates an initialized SDKProperties using the default location
// for the data directory.
func New() (SDKProperties, error) {
	return NewWithDataPath("")
}

// GetSDKVersion returns the version of the SDK or empty if not set.
// Use sdkcommon.New() to create an initialized SDKProperties struct.
func (sdk SDKProperties) GetSDKVersion() string {
	return sdk.version
}

// GetSDKDataPath returns the path to the directory for storing SDK related data,
//  or empty if not set.
// Use sdkcommon.New() to create an initialized SDKProperties struct.
func (sdk SDKProperties) GetSDKDataPath() string {
	return sdk.dataPath
}

// getSDKVersion reads the manifest JSON file and returns the "id" property.
func readSDKVersion(manifestFilePath string) (string, error) {
	manifestFile, err := os.Open(manifestFilePath)
	// if we os.Open returns an error then handle it
	if err != nil {
		return "", err
	}
	defer manifestFile.Close()
	data, err := ioutil.ReadAll(manifestFile)
	if err != nil {
		return "", err
	}

	var result map[string]interface{}
	if err := json.Unmarshal([]byte(data), &result); err != nil {
		return "", err
	}

	version, _ := result["id"].(string)
	return version, nil
}

// GetDefaultPackageRepoDir returns the path to the package repository.
// If the value has been set with `ffx`, use that value.
// Otherwise if there is a default target defined, return the target
// specific path.
// Lastly, if there is nothing, return the default repo path.
func (sdk SDKProperties) getDefaultPackageRepoDir(deviceName string) string {
	if deviceName != "" {
		return filepath.Join(sdk.GetSDKDataPath(), deviceName,
			"packages", "amber-files")
	}
	// As a last resort, `ffx` and the data are working as intended,
	// but no default has been configured, so fall back to the generic
	// legacy path.
	return filepath.Join(sdk.GetSDKDataPath(), "packages", "amber-files")
}

// GetToolsDir returns the path to the SDK tools for the current
// CPU architecture. This is implemented by default of getting the
// directory of the currently exeecuting binary.
func (sdk SDKProperties) GetToolsDir() (string, error) {
	exePath, err := os.Executable()
	if err != nil {
		return "", fmt.Errorf("Could not currently running file: %v", err)
	}
	dir, err := filepath.Abs(filepath.Dir(exePath))
	if err != nil {
		return "", fmt.Errorf("Could not get directory of currently running file: %s", err)
	}

	// This could be a symlink in a directory, so look for another common
	// tool (ffx). If it does not, try using the dir from argv[0].
	if FileExists(filepath.Join(dir, "ffx")) {
		return dir, nil
	}

	dir, err = filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		return "", fmt.Errorf("Could not get path of argv[0]: %v", err)
	}
	return dir, nil
}

// GetAvailableImages returns the images available for the given version and bucket. If
// bucket is not the default bucket, the images in the default bucket are also returned.
func (sdk SDKProperties) GetAvailableImages(version string, bucket string) ([]GCSImage, error) {
	var buckets []string
	var images []GCSImage

	if bucket == "" || bucket == defaultBucketName {
		buckets = []string{defaultBucketName}
	} else {
		buckets = []string{bucket, defaultBucketName}
	}

	for _, b := range buckets {
		url := fmt.Sprintf("gs://%v/development/%v/images*", b, version)
		args := []string{"ls", url}
		output, err := runGSUtil(args)
		if err != nil {
			return images, err
		}
		for _, line := range strings.Split(strings.TrimSuffix(string(output), "\n"), "\n") {
			if len(filepath.Base(line)) >= 4 {
				bucketVersion := filepath.Base(filepath.Dir(filepath.Dir(line)))
				name := filepath.Base(line)[:len(filepath.Base(line))-4]
				images = append(images, GCSImage{Bucket: b, Version: bucketVersion, Name: name})
			} else {
				log.Warningf("Could not parse image name: %v", line)
			}
		}
	}
	return images, nil
}

// GetPackageSourcePath returns the GCS path for the given values.
func (sdk SDKProperties) GetPackageSourcePath(version string, bucket string, image string) string {
	return fmt.Sprintf("gs://%s/development/%s/packages/%s.tar.gz", bucket, version, image)
}

// RunFFXDoctor runs common checks for the ffx tool and host environment and returns
// the stdout.
func (sdk SDKProperties) RunFFXDoctor() (string, error) {
	args := []string{"doctor"}
	return sdk.RunFFX(args, false)
}

func (f *FuchsiaDevice) String() string {
	return fmt.Sprintf("%s %s", f.SSHAddr, f.Name)
}

func (f *FuchsiaDevice) getIPAddressAndPort() (string, string) {
	host, port, err := net.SplitHostPort(f.SSHAddr)
	if err != nil {
		log.Debugf("Got an error from net.SplitHostPort(%#v): %v", f.SSHAddr, err)
		return "", ""
	}
	return host, port
}

// isUnknownInListOutput returns true if unknown is in the ffx output.
func (sdk SDKProperties) isUnknownInListOutput(discoveredDevices []*deviceInfo) bool {
	for _, currentDevice := range discoveredDevices {
		if strings.Contains(strings.TrimSpace(currentDevice.Nodename), UnknownTargetName) {
			return true
		}
	}
	return false
}

func (sdk SDKProperties) listDevicesWithFFX() ([]*deviceInfo, error) {
	args := []string{"--machine", "json", "target", "list"}
	output, err := sdk.RunFFX(args, false)
	if err != nil {
		return nil, fmt.Errorf("Unable to list devices, please try running 'ffx doctor': %v", err)
	}
	var discoveredDevices []*deviceInfo
	if len(output) == 0 {
		return discoveredDevices, nil
	}
	if err := json.Unmarshal([]byte(output), &discoveredDevices); err != nil {
		return nil, fmt.Errorf("Unable to unmarshal device info from ffx, please try running 'ffx doctor': %v", err)
	}

	return discoveredDevices, nil
}

// listDevices returns all available fuchsia devices.
func (sdk SDKProperties) listDevices() ([]*FuchsiaDevice, error) {
	var discoveredDevices []*deviceInfo
	var err error
	// List the devices using ffx. If unknown is in the output from ffx, we will try
	// `maxRetryCount` so that the device will show up with the name.
	// If after the `maxRetryCount` is reached and unknown is still in the output, the device
	// is unreachable.
	for tries := 0; tries < maxRetryCount; tries++ {
		discoveredDevices, err = sdk.listDevicesWithFFX()
		if err != nil {
			return nil, err
		}
		if !sdk.isUnknownInListOutput(discoveredDevices) {
			break
		}
		// This should only occur when the device is in unknown state, usually in the first
		// invocation of any of the f* tools.
		time.Sleep(sleepTimeInSeconds * time.Second)
	}

	var devices []*FuchsiaDevice

	for _, currentDevice := range discoveredDevices {
		if len(currentDevice.Addresses) == 0 {
			continue
		}
		sshAddr, err := sdk.getDeviceSSHAddress(currentDevice)
		// If we are unable to get the device ssh address, skip the device.
		if err != nil {
			log.Debugf("Failed to getDeviceSSHAddress for %s: %v", currentDevice.Nodename, err)
			sshAddr = ""
			continue
		}
		devices = append(devices, &FuchsiaDevice{
			SSHAddr: strings.TrimSpace(sshAddr),
			Name:    strings.TrimSpace(currentDevice.Nodename),
		})
	}
	return devices, nil
}

func (sdk SDKProperties) getDefaultFFXDevice() (string, error) {
	args := []string{"target", "default", "get"}
	output, err := sdk.RunFFX(args, false)
	if err != nil {
		return "", fmt.Errorf("Unable to get ffx default device, please try running 'ffx doctor': %v", err)
	}
	log.Debugf("FFX default device is: %v", output)
	return strings.TrimSpace(output), nil
}

func (sdk SDKProperties) getDeviceSSHAddress(device *deviceInfo) (string, error) {
	args := []string{"--target", device.Nodename, "target", "get-ssh-address"}
	output, err := sdk.RunFFX(args, false)
	if err != nil {
		return "", fmt.Errorf("Unable to get ssh address: %v", err)
	}
	return strings.TrimSpace(output), nil
}

func getCommonSSHArgs(sdk SDKProperties, customSSHConfig string, privateKey string,
	sshPort string) []string {

	var cmdArgs []string
	if customSSHConfig != "" {
		cmdArgs = append(cmdArgs, "-F", customSSHConfig)
	} else {
		cmdArgs = append(cmdArgs, "-F", getFuchsiaSSHConfigFile(sdk))
	}
	if privateKey != "" {
		cmdArgs = append(cmdArgs, "-i", privateKey)
	}
	if sshPort != "" {
		cmdArgs = append(cmdArgs, "-p", sshPort)
	}

	return cmdArgs
}

// RunSFTPCommand runs sftp (one of SSH's file copy tools).
// Setting toTarget to true will copy file SRC from host to DST on the target.
// Otherwise it will copy file from SRC from target to DST on the host.
// sshPort if non-empty will use this port to connect to the device.
// The return value is the error if any.
func (sdk SDKProperties) RunSFTPCommand(targetAddress string, customSSHConfig string, privateKey string,
	sshPort string, toTarget bool, src string, dst string) error {

	commonArgs := []string{"-q", "-b", "-"}
	if customSSHConfig == "" || privateKey == "" {
		if err := checkSSHConfig(sdk); err != nil {
			return err
		}
	}

	cmdArgs := getCommonSSHArgs(sdk, customSSHConfig, privateKey, sshPort)

	cmdArgs = append(cmdArgs, commonArgs...)
	if targetAddress == "" {
		return errors.New("target address must be specified")
	}
	// SFTP needs the [] around the ipv6 address, which is different than ssh.
	if strings.Contains(targetAddress, ":") {
		targetAddress = fmt.Sprintf("[%v]", targetAddress)
	}
	cmdArgs = append(cmdArgs, targetAddress)

	stdin := ""

	if toTarget {
		stdin = fmt.Sprintf("put %v %v", src, dst)
	} else {
		stdin = fmt.Sprintf("get %v %v", src, dst)
	}

	return runSFTP(cmdArgs, stdin)
}

// RunSSHCommand runs the command provided in args on the given target device.
// The customSSHconfig is optional and overrides the SSH configuration defined by the SDK.
// privateKey is optional to specify a private key to use to access the device.
// verbose adds the -v flag to ssh.
// sshPort if non-empty is used as the custom ssh port on the commandline.
// The return value is the stdout.
func (sdk SDKProperties) RunSSHCommand(targetAddress string, customSSHConfig string,
	privateKey string, sshPort string, verbose bool, args []string) (string, error) {

	cmdArgs, err := buildSSHArgs(sdk, targetAddress, customSSHConfig, privateKey, sshPort, verbose, args)
	if err != nil {
		return "", err
	}

	return runSSH(cmdArgs, false)
}

// RunSSHShell runs the command provided in args on the given target device and
// uses the system stdin, stdout, stderr.
// Returns when the ssh process exits.
// The customSSHconfig is optional and overrides the SSH configuration defined by the SDK.
// privateKey is optional to specify a private key to use to access the device.
// sshPort if non-empty is used as the custom ssh port on the commandline.
// verbose adds the -v flag to ssh.
// The return value is the stdout.
func (sdk SDKProperties) RunSSHShell(targetAddress string, customSSHConfig string,
	privateKey string, sshPort string, verbose bool, args []string) error {

	cmdArgs, err := buildSSHArgs(sdk, targetAddress, customSSHConfig, privateKey,
		sshPort, verbose, args)
	if err != nil {
		return err
	}
	_, err = runSSH(cmdArgs, true)
	return err

}

func buildSSHArgs(sdk SDKProperties, targetAddress string, customSSHConfig string,
	privateKey string, sshPort string, verbose bool, args []string) ([]string, error) {
	if customSSHConfig == "" || privateKey == "" {
		if err := checkSSHConfig(sdk); err != nil {
			return []string{}, err
		}
	}

	cmdArgs := getCommonSSHArgs(sdk, customSSHConfig, privateKey, sshPort)
	if verbose {
		cmdArgs = append(cmdArgs, "-v")
	}

	if targetAddress == "" {
		return cmdArgs, errors.New("target address must be specified")
	}
	cmdArgs = append(cmdArgs, targetAddress)

	cmdArgs = append(cmdArgs, args...)

	return cmdArgs, nil
}

func getFuchsiaSSHConfigFile(sdk SDKProperties) string {
	return filepath.Join(sdk.GetSDKDataPath(), "sshconfig")
}

/* This function creates the ssh keys needed to
 work with devices running Fuchsia. There are two parts, the keys and the config.

 There is a key for Fuchsia that is placed in a well-known location so that applications
 which need to access the Fuchsia device can all use the same key. This is stored in
 ${HOME}/.ssh/fuchsia_ed25519.

 The authorized key file used for paving is in ${HOME}/.ssh/fuchsia_authorized_keys.
 The private key used when ssh'ing to the device is in ${HOME}/.ssh/fuchsia_ed25519.


 The second part of is the sshconfig file used by the SDK when using SSH.
 This is stored in the Fuchsia SDK data directory named sshconfig.
 This script checks for the private key file being referenced in the sshconfig and
the matching version tag. If they are not present, the sshconfig file is regenerated.
*/

const sshConfigTag = "Fuchsia SDK config version 5 tag"

func checkSSHConfig(sdk SDKProperties) error {
	// The ssh configuration should not be modified.

	homeDir, err := GetUserHomeDir()
	if err != nil {
		return fmt.Errorf("SSH configuration requires a $HOME directory: %v", err)
	}
	userName, err := GetUsername()
	if err != nil {
		return fmt.Errorf("SSH configuration requires a user name: %v", err)
	}
	var (
		sshDir        = filepath.Join(homeDir, ".ssh")
		authFile      = filepath.Join(sshDir, "fuchsia_authorized_keys")
		keyFile       = filepath.Join(sshDir, "fuchsia_ed25519")
		sshConfigFile = getFuchsiaSSHConfigFile(sdk)
	)
	// If the public and private key pair exist, and the sshconfig
	// file is up to date, then our work here is done, return success.
	if FileExists(authFile) && FileExists(keyFile) && FileExists(sshConfigFile) {
		config, err := ioutil.ReadFile(sshConfigFile)
		if err == nil {
			if strings.Contains(string(config), sshConfigTag) {
				return nil
			}
		}
		// The version tag does not match, so remove the old config file.
		os.Remove(sshConfigFile)
	}

	if err := os.MkdirAll(sshDir, 0755); err != nil {
		return fmt.Errorf("Could not create %v: %v", sshDir, err)
	}

	// Check to migrate keys from old location
	if !FileExists(authFile) || !FileExists(keyFile) {
		if err := moveLegacyKeys(sdk, authFile, keyFile); err != nil {
			return fmt.Errorf("Could not migrate legacy SSH keys: %v", err)
		}
	}

	// Create keys if needed
	if !FileExists(authFile) || !FileExists(keyFile) {
		if !FileExists(keyFile) {
			hostname, _ := GetHostname()
			if hostname == "" {
				hostname = "unknown"
			}
			if err := generateSSHKey(keyFile, userName, hostname); err != nil {
				return fmt.Errorf("Could not generate private SSH key: %v", err)
			}
		}
		if err := generatePublicSSHKeyfile(keyFile, authFile); err != nil {
			return fmt.Errorf("Could not get public keys from private SSH key: %v", err)
		}
	}

	if err := writeSSHConfigFile(sshConfigFile, sshConfigTag, keyFile); err != nil {
		return fmt.Errorf("Could not write sshconfig file %v: %v", sshConfigFile, err)
	}
	return nil
}

func generateSSHKey(keyFile string, username string, hostname string) error {
	path, err := ExecLookPath("ssh-keygen")
	if err != nil {
		return fmt.Errorf("could not find ssh-keygen on path: %v", err)
	}
	args := []string{
		"-P", "",
		"-t", "ed25519",
		"-f", keyFile,
		"-C", fmt.Sprintf("%v@%v generated by Fuchsia GN SDK", username, hostname),
	}
	cmd := ExecCommand(path, args...)
	_, err = cmd.Output()
	if err != nil {
		var exitError *exec.ExitError
		if errors.As(err, &exitError) {
			return fmt.Errorf("%v: %v", string(exitError.Stderr), exitError)
		}
		return err
	}
	return nil
}

func generatePublicSSHKeyfile(keyFile string, authFile string) error {
	path, err := ExecLookPath("ssh-keygen")
	if err != nil {
		return fmt.Errorf("could not find ssh-keygen on path: %v", err)
	}
	args := []string{
		"-y",
		"-f", keyFile,
	}
	cmd := ExecCommand(path, args...)
	publicKey, err := cmd.Output()
	if err != nil {
		var exitError *exec.ExitError
		if errors.As(err, &exitError) {
			return fmt.Errorf("%v: %v", string(exitError.Stderr), exitError)
		}
		return err
	}

	if err := os.MkdirAll(filepath.Dir(authFile), 0755); err != nil {
		return err
	}

	output, err := os.Create(authFile)
	if err != nil {
		return err
	}
	defer output.Close()

	fmt.Fprintln(output, publicKey)
	return nil
}

func writeSSHConfigFile(sshConfigFile string, versionTag string, keyFile string) error {

	if err := os.MkdirAll(filepath.Dir(sshConfigFile), 0755); err != nil {
		return err
	}

	output, err := os.Create(sshConfigFile)
	if err != nil {
		return err
	}
	defer output.Close()

	fmt.Fprintf(output, "# %s\n", versionTag)
	fmt.Fprintf(output,
		`# Configure port 8022 for connecting to a device with the local address.
# This makes it possible to forward 8022 to a device connected remotely.
# The fuchsia private key is used for the identity.
Host 127.0.0.1
	Port 8022

Host ::1
	Port 8022

Host *
# Turn off refusing to connect to hosts whose key has changed
StrictHostKeyChecking no
CheckHostIP no

# Disable recording the known hosts
UserKnownHostsFile=/dev/null

# Do not forward auth agent connection to remote, no X11
ForwardAgent no
ForwardX11 no

# Connection timeout in seconds
ConnectTimeout=10

# Check for server alive in seconds, max count before disconnecting
ServerAliveInterval 1
ServerAliveCountMax 10

# Try to keep the master connection open to speed reconnecting.
ControlMaster auto
ControlPersist yes

# When expanded, the ControlPath below cannot have more than 90 characters
# (total of 108 minus 18 used by a random suffix added by ssh).
# '%%C' expands to 40 chars and there are 9 fixed chars, so '~' can expand to
# up to 41 chars, which is a reasonable limit for a user's home in most
# situations. If '~' expands to more than 41 chars, the ssh connection
# will fail with an error like:
#     unix_listener: path "..." too long for Unix domain socket
# A possible solution is to use /tmp instead of ~, but it has
# its own security concerns.
ControlPath=~/.ssh/fx-%%C

# Connect with user, use the identity specified.
User fuchsia
IdentitiesOnly yes
IdentityFile "%v"
GSSAPIDelegateCredentials no

`, keyFile)

	return nil
}

func moveLegacyKeys(sdk SDKProperties, destAuthFile string, destKeyFile string) error {

	// Check for legacy GN SDK key and copy it to the new location.
	var (
		legacySSHDir   = filepath.Join(sdk.GetSDKDataPath(), ".ssh")
		legacyKeyFile  = filepath.Join(legacySSHDir, "pkey")
		legacyAuthFile = filepath.Join(legacySSHDir, "authorized_keys")
	)
	if FileExists(legacyKeyFile) {
		fmt.Fprintf(os.Stderr, "Migrating legacy key file %v to %v\n", legacyKeyFile, destKeyFile)
		if err := os.Rename(legacyKeyFile, destKeyFile); err != nil {
			return err
		}
		if FileExists(legacyAuthFile) {
			if err := os.Rename(legacyAuthFile, destAuthFile); err != nil {
				return err
			}
		}
	}
	return nil
}

// GetValidPropertyNames returns the list of valid properties for a
// device configuration.
func (sdk SDKProperties) GetValidPropertyNames() []string {
	return validPropertyNames[:]
}

// IsValidProperty returns true if the property is a valid
// property name.
func (sdk SDKProperties) IsValidProperty(property string) bool {
	for _, item := range validPropertyNames {
		if item == property {
			return true
		}
	}
	return false
}

// GetFuchsiaProperty returns the value for the given property for the given device.
// If the device name is empty, the default device is used via GetDefaultDevice().
// It is an error if the property cannot be found.
func (sdk SDKProperties) GetFuchsiaProperty(device string, property string) (string, error) {
	deviceConfig, err := sdk.GetDefaultDevice(device)
	if err != nil {
		return "", fmt.Errorf("Could not read configuration data for %v : %v", device, err)
	}
	if deviceConfig.DeviceName != "" {
		device = deviceConfig.DeviceName
	}
	switch property {
	case BucketKey:
		return deviceConfig.Bucket, nil
	case DeviceIPKey:
		return deviceConfig.DeviceIP, nil
	case DeviceNameKey:
		return deviceConfig.DeviceName, nil
	case ImageKey:
		return deviceConfig.Image, nil
	case PackagePortKey:
		return deviceConfig.PackagePort, nil
	case PackageRepoKey:
		return deviceConfig.PackageRepo, nil
	case SSHPortKey:
		return deviceConfig.SSHPort, nil
	}
	return "", fmt.Errorf("Could not find property %v.%v", device, property)
}

func (sdk SDKProperties) updateConfigIfDeviceIsDiscoverable(deviceConfig *DeviceConfig, discoverableDevices []*FuchsiaDevice) DeviceConfig {
	for _, discoverableDevice := range discoverableDevices {
		if deviceConfig.DeviceName == discoverableDevice.Name {
			deviceConfig.Discoverable = true
			// If DeviceIP is empty, update it from ffx target list output.
			if deviceConfig.DeviceIP == "" {
				deviceConfig.DeviceIP, deviceConfig.SSHPort = discoverableDevice.getIPAddressAndPort()
			}
			return *deviceConfig
		}
	}
	deviceConfig.Discoverable = false
	return *deviceConfig
}

func (sdk SDKProperties) mergeDeviceConfigsWithDiscoverableDevices(configs []DeviceConfig) []DeviceConfig {
	visitedDevices := map[string]bool{}
	var finalConfigs []DeviceConfig
	// Get the devices that are discoverable.
	discoverableDevices, err := sdk.listDevices()
	if err != nil {
		log.Debugf("Got an error when listing devices: %v", err)
		return configs
	}
	if len(discoverableDevices) == 0 {
		return configs
	}

	for _, config := range configs {
		if visitedDevices[config.DeviceName] {
			continue
		}
		visitedDevices[config.DeviceName] = true
		sdk.updateConfigIfDeviceIsDiscoverable(&config, discoverableDevices)
		sdk.setDeviceDefaults(&config)
		finalConfigs = append(finalConfigs, config)
	}
	for _, discoverableDevice := range discoverableDevices {
		if visitedDevices[discoverableDevice.Name] {
			continue
		}
		visitedDevices[discoverableDevice.Name] = true
		ip, port := discoverableDevice.getIPAddressAndPort()
		newConfig := DeviceConfig{
			DeviceName:   discoverableDevice.Name,
			DeviceIP:     ip,
			SSHPort:      port,
			Discoverable: true,
		}
		sdk.setDeviceDefaults(&newConfig)
		finalConfigs = append(finalConfigs, newConfig)
	}
	return finalConfigs
}

// getConfiguredDevices gets a list of devices that are configured in ffx config.
func (sdk SDKProperties) getConfiguredDevices(isMigration bool) ([]DeviceConfig, error) {
	var configs []DeviceConfig
	// Get all config data.
	configData, err := getDeviceConfigurationData(sdk, deviceConfigurationKey)
	if err != nil {
		return configs, fmt.Errorf("Could not read configuration data : %v", err)
	}

	defaultDeviceName, err := sdk.getDefaultFFXDevice()
	if err != nil {
		return configs, err
	}

	// If the default device name is "", we don't need to check if we visited it.
	visitedDefaultDevice := defaultDeviceName == ""

	if deviceConfigMap, ok := configData[deviceConfigurationKey].(map[string]interface{}); ok {
		for k, v := range deviceConfigMap {
			if !isReservedProperty(k) {
				if device, ok := sdk.mapToDeviceConfig(k, v); ok {
					if defaultDeviceName == device.DeviceName {
						device.IsDefault = true
						visitedDefaultDevice = true
					}
					sdk.setDeviceDefaults(&device)
					configs = append(configs, device)
				}
			}
		}
	}
	// If we are migrating device configurations from global to user,
	// we don't want to append the default device if it wasn't seen already.
	if isMigration {
		return configs, nil
	}
	if !visitedDefaultDevice {
		newConfig := DeviceConfig{
			DeviceName: defaultDeviceName,
			IsDefault:  true,
		}
		sdk.setDeviceDefaults(&newConfig)
		configs = append(configs, newConfig)
	}
	return configs, nil
}

// GetDeviceConfigurations returns a list of all device configurations.
func (sdk SDKProperties) GetDeviceConfigurations() ([]DeviceConfig, error) {
	configs, err := sdk.getConfiguredDevices(false)
	if err != nil {
		return nil, err
	}
	return sdk.mergeDeviceConfigsWithDiscoverableDevices(configs), nil
}

// GetDeviceConfiguration returns the configuration for the device with the given name.
func (sdk SDKProperties) GetDeviceConfiguration(name string) (DeviceConfig, error) {
	var deviceConfig DeviceConfig

	dataKey := getDeviceDataKey([]string{name}, false)
	configData, err := getDeviceConfigurationData(sdk, dataKey)
	if err != nil {
		return deviceConfig, fmt.Errorf("Could not read configuration data : %v", err)
	}
	if len(configData) == 0 {
		deviceConfig = DeviceConfig{
			DeviceName: name,
		}
		sdk.setDeviceDefaults(&deviceConfig)
		return deviceConfig, nil
	}

	if deviceData, ok := configData[dataKey]; ok {
		if deviceConfig, ok := sdk.mapToDeviceConfig(name, deviceData); ok {
			defaultDeviceName, err := sdk.getDefaultFFXDevice()
			if err != nil {
				return deviceConfig, err
			}
			deviceConfig.IsDefault = deviceConfig.DeviceName == defaultDeviceName
			// Set the default values for the  device, even if not set explicitly
			// This centralizes the configuration into 1 place.
			sdk.setDeviceDefaults(&deviceConfig)
			return deviceConfig, nil
		}
		return deviceConfig, fmt.Errorf("Cannot parse DeviceConfig from %v", configData)
	}
	return deviceConfig, fmt.Errorf("Cannot parse DeviceData.%v from %v", name, configData)
}

// SetDeviceIP manually adds a target via `ffx target add`.
func (sdk SDKProperties) SetDeviceIP(deviceIP, sshPort string) error {
	if sshPort == "" {
		sshPort = DefaultSSHPort
	}
	fullAddr := net.JoinHostPort(deviceIP, sshPort)
	ffxTargetAddArgs := []string{"target", "add", fullAddr}
	log.Debugf("Adding target using ffx %s", ffxTargetAddArgs)
	if _, err := sdk.RunFFX(ffxTargetAddArgs, false); err != nil {
		return fmt.Errorf("unable to add target via ffx %s: %w", ffxTargetAddArgs, err)
	}
	return nil
}

// SaveDeviceConfiguration persists the given device configuration properties.
func (sdk SDKProperties) SaveDeviceConfiguration(newConfig DeviceConfig) error {
	// Create a map of key to value to store. Only write out values that are explicitly set to something
	// that is not the default.
	origConfig, err := sdk.GetDeviceConfiguration(newConfig.DeviceName)
	if err != nil {
		return err
	}
	defaultConfig := DeviceConfig{DeviceName: newConfig.DeviceName}
	sdk.setDeviceDefaults(&defaultConfig)

	dataMap := make(map[string]string)
	// If the value changed from the original, write it out. We only write configurations
	// to ffx if they are not the default unless a value was previously written.
	if origConfig.Bucket != newConfig.Bucket {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, BucketKey}, false)] = newConfig.Bucket
	}
	if origConfig.Image != newConfig.Image {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, ImageKey}, false)] = newConfig.Image
	}
	if origConfig.PackagePort != newConfig.PackagePort {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, PackagePortKey}, false)] = newConfig.PackagePort
	}
	if origConfig.PackageRepo != newConfig.PackageRepo {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, PackageRepoKey}, false)] = newConfig.PackageRepo
	}
	if newConfig.IsDefault {
		if err := sdk.setFFXDefaultDevice(newConfig.DeviceName); err != nil {
			return fmt.Errorf("unable to set default device via ffx: %v", err)
		}
	}

	for key, value := range dataMap {
		if err := writeConfigurationData(sdk, key, value); err != nil {
			return err
		}
	}
	return nil
}

// setFFXDefaultDevice sets the default device in ffx.
func (sdk SDKProperties) setFFXDefaultDevice(deviceName string) error {
	args := []string{"target", "default", "set", deviceName}
	log.Debugf("Setting default device via ffx: %v\n", args)
	_, err := sdk.RunFFX(args, false)
	return err
}

// unsetFFXDefaultDevice unsets the default device in ffx.
func (sdk SDKProperties) unsetFFXDefaultDevice() error {
	args := []string{"target", "default", "unset"}
	log.Debugf("Unsetting default device via ffx: %v\n", args)
	_, err := sdk.RunFFX(args, false)
	return err
}

// RemoveDeviceConfiguration removes the device settings for the given name.
func (sdk SDKProperties) RemoveDeviceConfiguration(deviceName string, isGlobal bool) error {
	dataKey := getDeviceDataKey([]string{deviceName}, isGlobal)

	args := []string{"config", "remove", dataKey}

	if isGlobal {
		args = append(args, []string{"--level", "global"}...)
	}

	if _, err := sdk.RunFFX(args, false); err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			return fmt.Errorf("Error removing %s configuration with data key %s: %s", deviceName, dataKey, string(exiterr.Stderr))
		}
		return fmt.Errorf("Error removing %s configuration with data key %s: %w", deviceName, dataKey, err)
	}

	defaultDeviceName, err := sdk.getDefaultFFXDevice()
	if err != nil {
		return err
	}
	if defaultDeviceName == deviceName && !isGlobal {
		if err := sdk.unsetFFXDefaultDevice(); err != nil {
			return fmt.Errorf("unable to unset default device via ffx: %v", err)
		}
	}
	return nil
}

// ResolveTargetAddress evaluates the deviceIP and deviceName passed in
// to determine the target IP address. This include consulting the configuration
// information set via `ffx`.
func (sdk SDKProperties) ResolveTargetAddress(deviceIP string, deviceName string) (DeviceConfig, error) {
	var (
		targetAddress string
		err           error
	)

	// If there is a deviceIP address, use it.
	if deviceIP != "" {
		defaultConfig := DeviceConfig{
			DeviceIP: deviceIP,
		}
		sdk.setDeviceDefaults(&defaultConfig)
		return defaultConfig, nil
	}

	config, err := sdk.GetDefaultDevice(deviceName)
	if err != nil {
		return DeviceConfig{}, err
	}

	targetAddress = config.DeviceIP
	if config.DeviceName != "" {
		deviceName = config.DeviceName
	}

	if deviceName == "" && targetAddress == "" {
		return DeviceConfig{}, fmt.Errorf("No devices found. %v", helpfulTipMsg)
	}

	if targetAddress == "" {
		return DeviceConfig{}, fmt.Errorf(`Cannot get target address for %v.
		Try running 'ffx target list'.`, deviceName)
	}

	return config, nil
}

// GetDefaultDevice gets the default device to use by default.
func (sdk SDKProperties) GetDefaultDevice(deviceName string) (DeviceConfig, error) {
	if err := sdk.MigrateGlobalData(); err != nil {
		return DeviceConfig{}, err
	}

	configs, err := sdk.GetDeviceConfigurations()
	if err != nil {
		return DeviceConfig{}, err
	}

	if deviceName != "" {
		for _, config := range configs {
			if config.DeviceName == deviceName {
				return config, nil
			}
		}
		return sdk.setDeviceDefaults(&DeviceConfig{
			DeviceName: deviceName,
		}), nil
	}

	var discoverableDevicesConfigs []DeviceConfig
	// Check if there is a default device configured, if there is use it.
	for _, config := range configs {
		if config.IsDefault {
			return config, nil
		}
		if config.Discoverable {
			discoverableDevicesConfigs = append(discoverableDevicesConfigs, config)
		}
	}

	if len(discoverableDevicesConfigs) == 0 {
		defaultConfig := DeviceConfig{}
		sdk.setDeviceDefaults(&defaultConfig)
		return defaultConfig, nil
	}

	if len(discoverableDevicesConfigs) > 1 {
		return DeviceConfig{}, fmt.Errorf("Multiple devices found. %v", helpfulTipMsg)
	}
	return discoverableDevicesConfigs[0], nil
}

// writeConfigurationData calls `ffx` to store the value at the specified key.
func writeConfigurationData(sdk SDKProperties, key string, value string) error {
	args := []string{"config", "set", key, value}
	if _, err := sdk.RunFFX(args, false); err != nil {
		return fmt.Errorf("Error writing %s = %s: %w", key, value, err)
	}
	return nil
}

// isDeviceInList checks if device name is in the list.
func isDeviceInList(devices []DeviceConfig, deviceName string) bool {
	for _, device := range devices {
		if device.DeviceName == deviceName {
			return true
		}
	}
	return false
}

// MigrateGlobalData migrates global DeviceConfiguration to user level using
// device_config key.
func (sdk SDKProperties) MigrateGlobalData() error {
	// Get all global config data in DeviceConfiguration. This doesn't look
	// at devices that are discoverable by ffx target list.
	configData, err := getDeviceConfigurationData(sdk, globalDeviceConfigurationKey)
	if err != nil {
		return fmt.Errorf("could not read global configuration data: %w", err)
	}
	// If there is no global configuration data, simply return.
	if configData == nil {
		return nil
	}

	// Get the list of already configured device in user level. We don't want to
	// migrate devices that are already configured in user level.
	// This doesn't look at devices that are discoverable by ffx target list.
	alreadyConfiguredDevices, err := sdk.getConfiguredDevices(true)
	if err != nil {
		return err
	}

	if deviceConfigMap, ok := configData[globalDeviceConfigurationKey].(map[string]interface{}); ok {
		for k, v := range deviceConfigMap {
			if !isReservedProperty(k) {
				if device, ok := sdk.mapToDeviceConfig(k, v); ok {
					if isDeviceInList(alreadyConfiguredDevices, device.DeviceName) {
						continue
					}
					// Save the device to user configuration. We purposely don't remove the device
					// in order to ensure that different versions of the tools still work and don't
					// require reconfiguration.
					if err := sdk.SaveDeviceConfiguration(device); err != nil {
						return fmt.Errorf("failed to migrate ffx device configurations from global to user: %w", err)
					}
				}
			}
		}
	}
	return nil
}

// getDeviceConfigurationData calls `ffx` to read the data at the specified key.
func getDeviceConfigurationData(sdk SDKProperties, key string) (map[string]interface{}, error) {
	var (
		data   map[string]interface{}
		err    error
		output string
	)

	args := []string{"config", "get", key}

	if output, err = sdk.RunFFX(args, false); err != nil {
		// Exit code of 2 means no value was found.
		if exiterr, ok := err.(*exec.ExitError); ok && exiterr.ExitCode() == 2 {
			return data, nil
		}
		return data, fmt.Errorf("Error reading %v: %v %v", key, err, output)
	}

	if len(output) > 0 {
		jsonString := string(output)

		// wrap the response in {} and double quote the key so it is suitable for json unmarshaling.
		fullJSONString := "{\"" + key + "\": " + jsonString + "}"
		err := json.Unmarshal([]byte(fullJSONString), &data)
		if err != nil {
			return data, fmt.Errorf("Error parsing configuration data %v: %s", err, fullJSONString)
		}
	}
	return data, nil
}

// RunFFX executes ffx with the given args, returning stdout. If there is an error,
// the error will usually be of type *ExitError.
func (sdk SDKProperties) RunFFX(args []string, interactive bool) (string, error) {
	toolsDir, err := sdk.GetToolsDir()
	if err != nil {
		return "", fmt.Errorf("Could not determine tools directory %v", err)
	}
	cmd := filepath.Join(toolsDir, "ffx")

	if ffxConfigPath, present := os.LookupEnv(FFXIsolatedEnvKey); present {
		args = append([]string{"--config", ffxConfigPath}, args...)
	}

	ffx := ExecCommand(cmd, args...)
	if interactive {
		ffx.Stderr = os.Stderr
		ffx.Stdout = os.Stdout
		ffx.Stdin = os.Stdin
		return "", ffx.Run()
	}
	output, err := ffx.Output()
	if err != nil {
		return "", err
	}
	return string(output), err
}

// isReservedProperty used to differentiate between properties used
// internally and device names.
func isReservedProperty(property string) bool {
	switch property {
	case defaultDeviceKey:
		return true
	}
	return false
}

// mapToDeviceConfig converts the map returned by json into a DeviceConfig struct.
func (sdk SDKProperties) mapToDeviceConfig(deviceName string, data interface{}) (DeviceConfig, bool) {
	var (
		device     DeviceConfig
		deviceData map[string]interface{}
		ok         bool
		value      string
	)

	device.DeviceName = deviceName

	if deviceData, ok = data.(map[string]interface{}); ok {
		for _, key := range validPropertyNames {
			// The Default flag, IP address, and SSH port are stored else where, so don't
			// try to key it from the map.
			if key == DefaultKey || key == DeviceIPKey || key == SSHPortKey {
				continue
			}
			// Use Sprintf to convert the value into a string.
			// This is done since some values are numeric and are
			// not unmarshalled as strings.
			if val, ok := deviceData[key]; ok {
				value = fmt.Sprintf("%v", val)
			} else {
				// Setting the value to empty string makes it that the device default
				// value is used instead.
				value = ""
			}
			switch key {
			case BucketKey:
				device.Bucket = value
			case ImageKey:
				device.Image = value
			case PackagePortKey:
				device.PackagePort = value
			case PackageRepoKey:
				device.PackageRepo = value
			}
		}
	}
	return sdk.setDeviceDefaults(&device), ok
}
