// 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 (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strings"

	"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 ")
)

// Default GCS bucket for prebuilt images and packages.
const defaultGCSbucket string = "fuchsia"

// 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 for storing data.
	deviceConfigurationKey string = "DeviceConfiguration"
	defaultDeviceKey       string = "_DEFAULT_DEVICE_"
)

const (
	defaultBucketName  string = "fuchsia"
	defaultSSHPort     string = "22"
	defaultPackagePort string = "8083"
)

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

// DeviceConfig holds all the properties that are configured
// for a given devce.
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"`
}

// SDKProperties holds the common data for SDK tools.
// These values should be set or initialized by calling
// (sdk *SDKProperties) Init().
type SDKProperties struct {
	dataPath                 string
	version                  string
	globalPropertiesFilename 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) string {
	var fullKey = []string{deviceConfigurationKey}
	return strings.Join(append(fullKey, segments...), ".")
}

// DefaultGetUserHomeDir is the default implmentation 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 implmentation 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 implmentation of GetHostname()
// to allow mocking of user.Current()
func DefaultGetHostname() (string, error) {
	return os.Hostname()
}

// GetUserHomeDir to allow mocking.
var GetUserHomeDir = DefaultGetUserHomeDir

// GetUsername to allow mocking.
var GetUsername = DefaultGetUsername

// GetHostname to allow mocking.
var GetHostname = DefaultGetHostname

// New creates an initialized SDKProperties
func New() (SDKProperties, error) {
	sdk := SDKProperties{}
	homeDir, err := GetUserHomeDir()
	if err != nil {
		return sdk, err
	}
	sdk.dataPath = filepath.Join(homeDir, ".fuchsia")

	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
		}
	} else {
		log.Warningf("Cannot find SDK manifest file %v", manifestFile)
	}

	sdk.globalPropertiesFilename = filepath.Join(sdk.dataPath, "global_ffx_props.json")
	err = initFFXGlobalConfig(sdk)
	return sdk, err
}

// GetSDKVersion returns the version of the SDK or empty if not set.
// Use sdkcommon.New() to create an initalized 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 initalized 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 `fconfig`, 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")
}

// GetDefaultDeviceName returns the name of the target device to use by default.
func (sdk SDKProperties) GetDefaultDeviceName() (string, error) {
	dataKey := getDeviceDataKey([]string{defaultDeviceKey})
	data, err := getDeviceConfiguationData(sdk, dataKey)
	if err != nil {
		return "", err
	}
	if name, ok := data[dataKey].(string); ok {
		return name, nil
	} else if len(data) == 0 {
		return "", nil
	}
	return "", fmt.Errorf("Cannot parse default device from %v", data)
}

// 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)
	}
	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 == defaultGCSbucket {
		buckets = []string{defaultGCSbucket}
	} else {
		buckets = []string{bucket, defaultGCSbucket}
	}

	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 {
				name := filepath.Base(line)[:len(filepath.Base(line))-4]
				images = append(images, GCSImage{Bucket: b, Version: version, 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)
}

//GetAddressByName returns the IPv6 address of the device.
func (sdk SDKProperties) GetAddressByName(deviceName string) (string, error) {
	toolsDir, err := sdk.GetToolsDir()
	if err != nil {
		return "", fmt.Errorf("Could not determine tools directory %v", err)
	}
	cmd := filepath.Join(toolsDir, "device-finder")

	args := []string{"resolve", "-device-limit", "1", "-ipv4=false", deviceName}

	output, err := ExecCommand(cmd, args...).Output()
	if err != nil {
		var exitError *exec.ExitError
		if errors.As(err, &exitError) {
			return "", fmt.Errorf("%v: %v", string(exitError.Stderr), exitError)
		} else {
			return "", err
		}
	}
	return strings.TrimSpace(string(output)), nil
}

// 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.
// The return value is the stdout.
func (sdk SDKProperties) RunSSHCommand(targetAddress string, customSSHConfig string, privateKey string, verbose bool, args []string) (string, error) {

	cmdArgs, err := buildSSHArgs(sdk, targetAddress, customSSHConfig, privateKey, 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.
// verbose adds the -v flag to ssh.
// The return value is the stdout.
func (sdk SDKProperties) RunSSHShell(targetAddress string, customSSHConfig string, privateKey string, verbose bool, args []string) error {

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

}

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

	var cmdArgs []string
	if customSSHConfig != "" {
		cmdArgs = append(cmdArgs, "-F", customSSHConfig)
	} else {
		cmdArgs = []string{"-F", getFuchsiaSSHConfigFile(sdk)}
	}
	if privateKey != "" {
		cmdArgs = append(cmdArgs, "-i", privateKey)
	}
	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 generate private SSH key: %v", err)
			}
		}
		if err := generatePublicSSHKeyfile(keyFile, authFile); err != nil {
			return fmt.Errorf("Could get public keys from private SSH key: %v", err)
		}
	}

	if err := writeSSHConfigFile(sshConfigFile, sshConfigTag, keyFile); err != nil {
		return fmt.Errorf("Could 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)
		} else {
			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)
		} else {
			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 GetDefaultDeviceName().
// It is an error if the property cannot be found.
func (sdk SDKProperties) GetFuchsiaProperty(device string, property string) (string, error) {
	var err error
	deviceName := device
	if deviceName == "" {
		if deviceName, err = sdk.GetDefaultDeviceName(); err != nil {
			return "", err
		}
	}
	deviceConfig, err := sdk.GetDeviceConfiguration(deviceName)
	if err != nil {
		return "", fmt.Errorf("Could not read configuration data for %v : %v", deviceName, err)
	}

	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", deviceName, property)
}

// GetDeviceConfigurations returns a list of all device configurations.
func (sdk SDKProperties) GetDeviceConfigurations() ([]DeviceConfig, error) {
	var configs []DeviceConfig

	// Get all config data.
	configData, err := getDeviceConfiguationData(sdk, deviceConfigurationKey)
	if err != nil {
		return configs, fmt.Errorf("Could not read configuration data : %v", err)
	}
	if len(configData) == 0 {
		return configs, nil
	}

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

	if deviceConfigMap, ok := configData[deviceConfigurationKey].(map[string]interface{}); ok {
		for k, v := range deviceConfigMap {
			if !isReservedProperty(k) {
				if device, ok := mapToDeviceConfig(v); ok {
					device.IsDefault = defaultDeviceName == device.DeviceName
					configs = append(configs, device)
				}
			}
		}
		return configs, nil

	}
	return configs, fmt.Errorf("Could not read configuration data: %v", configData)
}

// 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})
	configData, err := getDeviceConfiguationData(sdk, dataKey)
	if err != nil {
		return deviceConfig, fmt.Errorf("Could not read configuration data : %v", err)
	}
	if len(configData) == 0 {
		return deviceConfig, nil
	}

	if deviceData, ok := configData[dataKey]; ok {
		if deviceConfig, ok := mapToDeviceConfig(deviceData); ok {
			defaultDeviceName, err := sdk.GetDefaultDeviceName()
			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)
}

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

	dataMap := make(map[string]string)
	dataMap[getDeviceDataKey([]string{newConfig.DeviceName, DeviceNameKey})] = newConfig.DeviceName
	if origConfig.Bucket != newConfig.Bucket {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, BucketKey})] = newConfig.Bucket
	} else {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, BucketKey})] = ""
	}
	if origConfig.DeviceIP != newConfig.DeviceIP {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, DeviceIPKey})] = newConfig.DeviceIP
	} else {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, DeviceIPKey})] = ""
	}
	if origConfig.Image != newConfig.Image {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, ImageKey})] = newConfig.Image
	} else {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, ImageKey})] = ""
	}
	if origConfig.PackagePort != newConfig.PackagePort {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, PackagePortKey})] = newConfig.PackagePort
	} else {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, PackagePortKey})] = ""
	}
	if origConfig.PackageRepo != newConfig.PackageRepo {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, PackageRepoKey})] = newConfig.PackageRepo
	} else {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, PackageRepoKey})] = ""
	}
	if origConfig.SSHPort != newConfig.SSHPort {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, SSHPortKey})] = newConfig.SSHPort
	} else {
		dataMap[getDeviceDataKey([]string{newConfig.DeviceName, SSHPortKey})] = ""
	}
	if newConfig.IsDefault {
		dataMap[getDeviceDataKey([]string{defaultDeviceKey})] = newConfig.DeviceName
	}

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

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

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

	if _, err := runFFX(sdk, args); err != nil {
		return fmt.Errorf("Error removing %s configuration: %v", deviceName, err)
	}

	defaultDeviceName, err := sdk.GetDefaultDeviceName()
	if err != nil {
		return err
	}
	if defaultDeviceName == deviceName {
		err := writeConfigurationData(sdk, getDeviceDataKey([]string{defaultDeviceKey}), "")
		if err != nil {
			return err
		}
	}
	return nil
}

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

	// If  there is a deviceIP address, use it.
	if deviceIP != "" {
		targetAddress = deviceIP
	} else {
		// No explicit address, use the name
		if deviceName == "" {
			// No name passed in, use the default name.
			if deviceName, err = sdk.GetDefaultDeviceName(); err != nil {
				return "", fmt.Errorf("could not determine default device name: %v", err)
			}
		}
		if deviceName == "" {
			// No address specified, no device name specified, and no device configured as the default.
			return "", errors.New("invalid arguments. Need to specify --device-ip or --device-name or use fconfig to configure a default device")
		}

		// look up a configured address by devicename
		targetAddress, err = sdk.GetFuchsiaProperty(deviceName, DeviceIPKey)
		if err != nil {
			return "", fmt.Errorf("could not read configuration information for  %v: %v", deviceName, err)
		}
		// if still nothing, resolve the device address by name
		if targetAddress == "" {
			if targetAddress, err = sdk.GetAddressByName(deviceName); err != nil {
				return "", fmt.Errorf("cannot get target address for %v: %v", deviceName, err)
			}
		}
	}
	if targetAddress == "" {
		return "", fmt.Errorf("could not get target device IP address for %v", deviceName)
	}
	return targetAddress, nil
}

func initFFXGlobalConfig(sdk SDKProperties) error {
	args := []string{"config", "env"}
	var (
		err    error
		output []byte
		line   string
	)
	if output, err = runFFX(sdk, args); err != nil {
		return fmt.Errorf("Error getting config environment %v", err)
	}
	reader := bufio.NewReader(bytes.NewReader(output))
	hasGlobal := false
	for !hasGlobal {
		line, err = reader.ReadString('\n')
		if err != nil {
			if err.Error() == "EOF" {
				break
			} else {
				return err
			}
		}
		if strings.HasPrefix(strings.TrimSpace(line), "Global") {
			break
		}
	}
	doSetEnv := len(line) == 0
	if len(line) > 0 {
		const (
			prefix    = "Global:"
			prefixLen = len(prefix)
		)
		index := strings.Index(line, "Global:")
		if index > len(line) {
			return fmt.Errorf("Cannot parse `Global:` prefix from %v", line)
		}
		filename := strings.TrimSpace(line[index+prefixLen:])
		_, err := os.Stat(filename)
		doSetEnv = os.IsNotExist(err)

	}
	if doSetEnv {
		// Create the global config level
		if len(sdk.globalPropertiesFilename) == 0 {
			return fmt.Errorf("Cannot initialize property config, global file name is empty: %v", sdk)
		}
		args := []string{"config", "env", "set", sdk.globalPropertiesFilename, "--level", "global"}
		if _, err := runFFX(sdk, args); err != nil {
			return fmt.Errorf("Error initializing global properties environment: %v", err)
		}
	}
	return 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", "--level", "global", key, value}
	if output, err := runFFX(sdk, args); err != nil {
		return fmt.Errorf("Error writing %v = %v: %v %v", key, value, err, string(output))
	}
	return nil
}

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

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

	if output, err = runFFX(sdk, args); err != nil {
		return data, fmt.Errorf("Error reading %v: %v %v", key, err, string(output))
	}
	if len(output) > 0 {
		jsonString := string(output)

		// Check for the key not being set.
		if strings.HasSuffix(jsonString, ": none\n") {
			return data, nil
		}

		// wrap the response in {} and double quote the key so it is suitable for json unmarshaling.
		index := strings.IndexByte(jsonString, ':')
		fullJSONString := "{\"" + jsonString[:index] + "\"" + jsonString[index:] + "}"
		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 runFFX(sdk SDKProperties, args []string) ([]byte, error) {
	toolsDir, err := sdk.GetToolsDir()
	if err != nil {
		return []byte{}, fmt.Errorf("Could not determine tools directory %v", err)
	}
	cmd := filepath.Join(toolsDir, "ffx")

	ffx := ExecCommand(cmd, args...)

	output, err := ffx.Output()
	if err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			return []byte{}, fmt.Errorf("Error %v running ffx: %v", exiterr.ExitCode(), string(exiterr.Stderr))
		}
	}
	return output, nil
}

// isReservedProperty used to differenciate 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 mapToDeviceConfig(data interface{}) (DeviceConfig, bool) {
	var (
		device     DeviceConfig
		deviceData map[string]interface{}
		ok         bool
		value      string
	)

	if deviceData, ok = data.(map[string]interface{}); ok {
		for _, key := range validPropertyNames {
			// the Default flag is stored else where, so don't try to
			// key it from the map.
			if key == DefaultKey {
				continue
			}
			if val, ok := deviceData[key].(string); ok {
				value = val
			} else {
				fmt.Fprintf(os.Stderr, "Cannot get %v from %v", key, deviceData)
				continue
			}
			switch key {
			case BucketKey:
				device.Bucket = value
			case DeviceIPKey:
				device.DeviceIP = value
			case DeviceNameKey:
				device.DeviceName = value
			case ImageKey:
				device.Image = value
			case PackagePortKey:
				device.PackagePort = value
			case PackageRepoKey:
				device.PackageRepo = value
			case SSHPortKey:
				device.SSHPort = value
			}
		}
	}
	return device, ok
}
