// Copyright 2021 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 ffxutil provides support for running ffx commands.
package ffxutil

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"go.fuchsia.dev/fuchsia/tools/bootserver"
	botanistconstants "go.fuchsia.dev/fuchsia/tools/botanist/constants"
	"go.fuchsia.dev/fuchsia/tools/build"
	"go.fuchsia.dev/fuchsia/tools/lib/ffxutil/constants"
	"go.fuchsia.dev/fuchsia/tools/lib/jsonutil"
	"go.fuchsia.dev/fuchsia/tools/lib/logger"
	"go.fuchsia.dev/fuchsia/tools/lib/retry"
	"go.fuchsia.dev/fuchsia/tools/lib/subprocess"
)

const (
	// The name of the snapshot zip file that gets outputted by `ffx target snapshot`.
	// Keep in sync with //src/developer/ffx/plugins/target/snapshot/src/lib.rs.
	snapshotZipName = "snapshot.zip"

	// The environment variable that ffx uses to create an isolated instance.
	FFXIsolateDirEnvKey = "FFX_ISOLATE_DIR"

	// The name of the ffx env config file.
	ffxEnvFilename = ".ffx_env"
)

type LogLevel string

const (
	Off   LogLevel = "Off"
	Error LogLevel = "Error"
	Warn  LogLevel = "Warn"
	Info  LogLevel = "Info"
	Debug LogLevel = "Debug"
	Trace LogLevel = "Trace"
)

func getCommand(
	runner *subprocess.Runner,
	stdout, stderr io.Writer,
	args ...string,
) *exec.Cmd {
	return runner.Command(args, subprocess.RunOptions{
		Stdout: stdout,
		Stderr: stderr,
	})
}

// FFXInstance takes in a path to the ffx tool and runs ffx commands with the provided config.
type FFXInstance struct {
	ctx     context.Context
	ffxPath string

	runner     *subprocess.Runner
	stdout     io.Writer
	stderr     io.Writer
	target     string
	env        []string
	isolateDir string
}

// ConfigSettings contains settings to apply to the ffx configs at the specified config level.
type ConfigSettings struct {
	Level    string
	Settings map[string]any
}

// Output for get-artifacts
type ProductArtifacts struct {
	Ok struct {
		Paths []string `json:"paths"`
	} `json:"ok"`
	UserError struct {
		Message string `json:"message"`
	} `json:"user_error"`
	UnexpectedError struct {
		Message string `json:"message"`
	} `json:"unexpected_error"`
}

// Output for get-image-path
type ProductImagePath struct {
	Ok struct {
		Path string `json:"path"`
	} `json:"ok"`
	UserError struct {
		Message string `json:"message"`
	} `json:"user_error"`
	UnexpectedError struct {
		Message string `json:"message"`
	} `json:"unexpected_error"`
}

// FFXWithTarget returns a copy of the provided ffx instance associated with
// the provided target. This copy should use the same ffx daemon but run
// commands with the new target.
func FFXWithTarget(ffx *FFXInstance, target string) *FFXInstance {
	return &FFXInstance{
		ctx:        ffx.ctx,
		ffxPath:    ffx.ffxPath,
		runner:     ffx.runner,
		stdout:     ffx.stdout,
		stderr:     ffx.stderr,
		target:     target,
		env:        ffx.env,
		isolateDir: ffx.isolateDir,
	}
}

// NewFFXInstance creates an isolated FFXInstance.
func NewFFXInstance(
	ctx context.Context,
	ffxPath string,
	dir string,
	env []string,
	target, sshKey string,
	outputDir string,
	extraConfigSettings ...ConfigSettings,
) (*FFXInstance, error) {
	if ffxPath == "" {
		return nil, nil
	}
	absOutputDir, err := filepath.Abs(outputDir)
	if err != nil {
		return nil, err
	}
	if err := os.MkdirAll(absOutputDir, os.ModePerm); err != nil {
		return nil, err
	}

	env = append(os.Environ(), env...)
	env = append(env, fmt.Sprintf("%s=%s", FFXIsolateDirEnvKey, absOutputDir))
	absFFXPath, err := filepath.Abs(ffxPath)
	if err != nil {
		return nil, err
	}
	ffx := &FFXInstance{
		ctx:        ctx,
		ffxPath:    absFFXPath,
		runner:     &subprocess.Runner{Dir: dir, Env: env},
		stdout:     os.Stdout,
		stderr:     os.Stderr,
		target:     target,
		env:        env,
		isolateDir: absOutputDir,
	}
	ffxEnvFilepath := filepath.Join(ffx.isolateDir, ffxEnvFilename)
	globalConfigFilepath := filepath.Join(ffx.isolateDir, "global_config.json")
	userConfigFilepath := filepath.Join(ffx.isolateDir, "user_config.json")
	ffxEnvSettings := map[string]any{
		"user":   userConfigFilepath,
		"global": globalConfigFilepath,
	}
	// Set these fields in the global config for tests that don't use this library
	// and don't set their own isolated env config.
	globalConfigSettings := map[string]any{
		// This is a config "alias" for various other config values -- disabling
		// metrics, device discovery, device auto-connection, etc.
		"ffx.isolated": true,
	}
	configSettings := map[string]any{
		"log.dir":                      filepath.Join(absOutputDir, "ffx_logs"),
		"ffx.subtool-search-paths":     filepath.Dir(absFFXPath),
		"target.default":               target,
		"test.experimental_json_input": true,
	}
	if sshKey != "" {
		sshKey, err = filepath.Abs(sshKey)
		if err != nil {
			return nil, err
		}
		configSettings["ssh.priv"] = []string{sshKey}
	}
	for _, settings := range extraConfigSettings {
		if settings.Level == "global" {
			for key, val := range settings.Settings {
				globalConfigSettings[key] = val
			}
		} else {
			for key, val := range settings.Settings {
				configSettings[key] = val
			}
		}
	}
	ffxCmds := [][]string{}
	if deviceAddr := os.Getenv(botanistconstants.DeviceAddrEnvKey); deviceAddr != "" {
		globalConfigSettings["discovery.mdns.enabled"] = false
		ffxCmds = append(ffxCmds, []string{"target", "add", deviceAddr, "--nowait"})
	}
	if err := writeConfigFile(globalConfigFilepath, globalConfigSettings); err != nil {
		return nil, fmt.Errorf("failed to write ffx global config at %s: %w", globalConfigFilepath, err)
	}
	if err := writeConfigFile(userConfigFilepath, configSettings); err != nil {
		return nil, fmt.Errorf("failed to write ffx user config at %s: %w", userConfigFilepath, err)
	}
	if err := writeConfigFile(ffxEnvFilepath, ffxEnvSettings); err != nil {
		return nil, fmt.Errorf("failed to write ffx env file at %s: %w", ffxEnvFilepath, err)
	}
	for _, args := range ffxCmds {
		if err := ffx.Run(ctx, args...); err != nil {
			if stopErr := ffx.Stop(); stopErr != nil {
				logger.Debugf(ctx, "failed to stop daemon: %s", stopErr)
			}
			return nil, fmt.Errorf("failed to run ffx cmd: %v: %w", args, err)
		}
	}
	return ffx, nil
}

func writeConfigFile(configPath string, configSettings map[string]any) error {
	data := make(map[string]any)
	for key, val := range configSettings {
		parts := strings.Split(key, ".")
		datakey := data
		for i, subkey := range parts {
			if i == len(parts)-1 {
				datakey[subkey] = val
			} else {
				if _, ok := datakey[subkey]; !ok {
					datakey[subkey] = make(map[string]any)
				}
				datakey = datakey[subkey].(map[string]any)
			}
		}
	}
	j, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		return fmt.Errorf("marshal ffx config: %w", err)
	}
	if err := os.WriteFile(configPath, j, 0o600); err != nil {
		return fmt.Errorf("writing ffx config to file: %w", err)
	}
	return nil
}

func (f *FFXInstance) Env() []string {
	return f.env
}

func (f *FFXInstance) SetTarget(target string) {
	f.target = target
}

func (f *FFXInstance) Stdout() io.Writer {
	return f.stdout
}

func (f *FFXInstance) Stderr() io.Writer {
	return f.stderr
}

// SetStdoutStderr sets the stdout and stderr for the ffx commands to write to.
func (f *FFXInstance) SetStdoutStderr(stdout, stderr io.Writer) {
	f.stdout = stdout
	f.stderr = stderr
}

// SetLogLevel sets the log-level in the ffx instance's associated config.
func (f *FFXInstance) SetLogLevel(ctx context.Context, level LogLevel) error {
	return f.ConfigSet(ctx, "log.level", string(level))
}

// ConfigSet sets a field in the ffx instance's associated config.
func (f *FFXInstance) ConfigSet(ctx context.Context, key, value string) error {
	return f.Run(ctx, "config", "set", key, value)
}

// Command returns an *exec.Cmd to run ffx with the provided args.
func (f *FFXInstance) Command(args ...string) *exec.Cmd {
	args = append([]string{f.ffxPath, "--isolate-dir", f.isolateDir}, args...)
	return getCommand(f.runner, f.stdout, f.stderr, args...)
}

// CommandWithTarget returns a Command to run with the associated target.
func (f *FFXInstance) CommandWithTarget(args ...string) *exec.Cmd {
	args = append([]string{"--target", f.target}, args...)
	return f.Command(args...)
}

// RunWithTimeout runs ffx with the associated config and provided args.
func (f *FFXInstance) RunWithTimeout(ctx context.Context, timeout time.Duration, args ...string) error {
	cmd := f.Command(args...)
	if timeout > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, time.Duration(timeout)*time.Second)
		defer cancel()
	}
	if err := f.runner.RunCommand(ctx, cmd); err != nil {
		return fmt.Errorf("%s (%s): %w", constants.CommandFailedMsg, cmd.String(), err)
	}
	return nil
}

// Run runs ffx with the associated config and provided args.
func (f *FFXInstance) Run(ctx context.Context, args ...string) error {
	// By default, runs ffx commands with 5 minutes timeout.
	return f.RunWithTimeout(ctx, 5*time.Minute, args...)
}

// RunWithTarget runs ffx with the associated target.
func (f *FFXInstance) RunWithTarget(ctx context.Context, args ...string) error {
	args = append([]string{"--target", f.target}, args...)
	return f.Run(ctx, args...)
}

// RunWithTargetAndTimeout runs ffx with the associated target and timeout.
func (f *FFXInstance) RunWithTargetAndTimeout(ctx context.Context, timeout time.Duration, args ...string) error {
	args = append([]string{"--target", f.target}, args...)
	return f.RunWithTimeout(ctx, timeout, args...)
}

// RunAndGetOutput runs ffx with the provided args and returns the stdout.
func (f *FFXInstance) RunAndGetOutput(ctx context.Context, args ...string) (string, error) {
	origStdout := f.stdout
	var output bytes.Buffer
	f.stdout = io.MultiWriter(&output, origStdout)
	defer func() {
		f.stdout = origStdout
	}()
	if err := f.Run(ctx, args...); err != nil {
		return strings.TrimSpace(output.String()), err
	}
	return strings.TrimSpace(output.String()), nil
}

// WaitForDaemon tries a few times to check that the daemon is up
// and returns an error if it fails to respond.
func (f *FFXInstance) WaitForDaemon(ctx context.Context) error {
	// Discard the stderr since it'll return a string caught by
	// tefmocheck if the daemon isn't ready yet.
	origStderr := f.stderr
	var output bytes.Buffer
	f.stderr = &output
	defer func() {
		f.stderr = origStderr
	}()
	err := retry.Retry(ctx, retry.WithMaxAttempts(retry.NewConstantBackoff(time.Second), 3), func() error {
		return f.RunWithTimeout(ctx, 0, "daemon", "echo")
	}, nil)
	if err != nil {
		logger.Warningf(ctx, "failed to echo daemon: %s", output.String())
	}
	return err
}

// Stop stops the daemon.
func (f *FFXInstance) Stop() error {
	// Wait up to 4000ms for daemon to shut down.
	return f.Run(context.Background(), "daemon", "stop", "-t", "4000")
}

// BootloaderBoot RAM boots the target.
func (f *FFXInstance) BootloaderBoot(ctx context.Context, serialNum, productBundle string) error {
	args := []string{
		"--target", serialNum,
		"--config", "{\"ffx\": {\"fastboot\": {\"inline_target\": true}}}",
		"target", "bootloader",
	}
	args = append(args, "--product-bundle", productBundle)
	args = append(args, "boot")
	return f.RunWithTimeout(ctx, 0, args...)
}

// List lists all available targets.
func (f *FFXInstance) List(ctx context.Context, args ...string) error {
	return f.Run(ctx, append([]string{"target", "list"}, args...)...)
}

// TargetWait waits until the target becomes available.
func (f *FFXInstance) TargetWait(ctx context.Context) error {
	return f.RunWithTarget(ctx, "target", "wait")
}

// Test runs a test suite.
func (f *FFXInstance) Test(
	ctx context.Context,
	testList build.TestList,
	outDir string,
	args ...string,
) (*TestRunResult, error) {
	// Write the test def to a file and store in the outDir to upload with the test outputs.
	if err := os.MkdirAll(outDir, os.ModePerm); err != nil {
		return nil, err
	}
	testFile := filepath.Join(outDir, "test-list.json")
	if err := jsonutil.WriteToFile(testFile, testList); err != nil {
		return nil, err
	}
	// Create a new subdirectory within outDir to pass to --output-directory which is expected to be
	// empty.
	testOutputDir := filepath.Join(outDir, "test-outputs")
	f.RunWithTargetAndTimeout(
		ctx,
		0,
		append(
			[]string{
				"test",
				"run",
				"--continue-on-timeout",
				"--test-file",
				testFile,
				"--output-directory",
				testOutputDir,
				"--show-full-moniker-in-logs",
			},
			args...)...)

	return GetRunResult(testOutputDir)
}

// Snapshot takes a snapshot of the target's state and saves it to outDir/snapshotFilename.
func (f *FFXInstance) Snapshot(ctx context.Context, outDir string, snapshotFilename string) error {
	err := f.RunWithTarget(ctx, "target", "snapshot", "--dir", outDir)
	if err != nil {
		return err
	}
	if snapshotFilename != "" && snapshotFilename != snapshotZipName {
		return os.Rename(
			filepath.Join(outDir, snapshotZipName),
			filepath.Join(outDir, snapshotFilename),
		)
	}
	return nil
}

// GetConfig shows the ffx config.
func (f *FFXInstance) GetConfig(ctx context.Context) error {
	return f.Run(ctx, "config", "get")
}

// GetSshPrivateKey returns the file path for the ssh private key.
func (f *FFXInstance) GetSshPrivateKey(ctx context.Context) (string, error) {
	// Check that the keys exist and are valid
	if err := f.Run(ctx, "config", "check-ssh-keys"); err != nil {
		return "", err
	}
	key, err := f.RunAndGetOutput(ctx, "config", "get", "ssh.priv")
	if err != nil {
		return "", err
	}

	// strip quotes if present.
	key = strings.Replace(key, "\"", "", -1)
	return key, nil
}

// GetSshAuthorizedKeys returns the file path for the ssh auth keys.
func (f *FFXInstance) GetSshAuthorizedKeys(ctx context.Context) (string, error) {
	// Check that the keys exist and are valid
	if err := f.Run(ctx, "config", "check-ssh-keys"); err != nil {
		return "", err
	}
	key, err := f.RunAndGetOutput(ctx, "config", "get", "ssh.pub")
	if err != nil {
		return "", err
	}

	// strip quotes if present.
	key = strings.Replace(key, "\"", "", -1)
	return key, nil
}

// GetPBArtifacts returns a list of the artifacts required for the specified artifactsGroup (flash or emu).
// The returned list are relative paths to the pbPath.
func (f *FFXInstance) GetPBArtifacts(ctx context.Context, pbPath string, artifactsGroup string) ([]string, error) {
	raw, err := f.RunAndGetOutput(ctx, "--machine", "json", "product", "get-artifacts", pbPath, "-r", "-g", artifactsGroup)

	return processPBArtifactsResult(raw, err)
}

func processPBArtifactsResult(raw string, err error) ([]string, error) {

	if raw == "" {
		if err != nil {
			return nil, err
		}
		return nil, fmt.Errorf("No output received from command")

	}

	// If there was an error, parse the output first since it will be a stable interface, otherwise fall back.
	var result ProductArtifacts
	err = json.Unmarshal([]byte(raw), &result)
	if err != nil {
		return nil, fmt.Errorf("Error parsing output %s: %v", raw, err)
	}
	if result.UnexpectedError.Message != "" {
		return nil, fmt.Errorf("unexpected error: %s", result.UnexpectedError.Message)
	}
	if result.UserError.Message != "" {
		return nil, fmt.Errorf("user error: %s", result.UserError.Message)
	}
	return result.Ok.Paths, nil
}

// GetImageFromPB returns an image from a product bundle.
func (f *FFXInstance) GetImageFromPB(ctx context.Context, pbPath string, slot string, imageType string, bootloader string) (*bootserver.Image, error) {
	args := []string{"--machine", "json", "product", "get-image-path", pbPath, "-r"}
	if slot != "" && imageType != "" && bootloader == "" {
		args = append(args, "--slot", slot, "--image-type", imageType)
	} else if bootloader != "" && slot == "" && imageType == "" {
		args = append(args, "--bootloader", bootloader)
	} else {
		return nil, fmt.Errorf("either slot and image type should be provided or bootloader "+
			"should be provided, not both: slot: %s, imageType: %s, bootloader: %s", slot, imageType, bootloader)
	}
	raw, err := f.RunAndGetOutput(ctx, args...)

	return processImageFromPBResult(pbPath, raw, err)
}

func processImageFromPBResult(pbPath string, raw string, err error) (*bootserver.Image, error) {
	if raw == "" {
		if err != nil {
			return nil, err
		}
		return nil, fmt.Errorf("No output received from command")

	}

	var result ProductImagePath
	err = json.Unmarshal([]byte(raw), &result)
	if err != nil {
		return nil, fmt.Errorf("Error parsing output %s: %v", raw, err)
	}

	if result.UnexpectedError.Message != "" || result.UserError.Message != "" {
		// An error is returned if the image cannot be found in the product bundle
		// which is ok.
		return nil, nil
	}

	imagePath := filepath.Join(pbPath, result.Ok.Path)
	buildImg := build.Image{Name: result.Ok.Path, Path: imagePath}
	reader, err := os.Open(imagePath)
	if err != nil {
		return nil, err
	}
	fi, err := reader.Stat()
	if err != nil {
		return nil, err
	}
	image := bootserver.Image{
		Image:  buildImg,
		Reader: reader,
		Size:   fi.Size(),
	}

	return &image, nil
}
