// 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"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"time"

	"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/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 JSON Pointer (https://tools.ietf.org/html/rfc6901) to log level in the config.
	logLevelJsonPointer = "/log/level"
)

type LogLevel string

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

func runCommand(
	ctx context.Context,
	runner *subprocess.Runner,
	stdout, stderr io.Writer,
	args ...string,
) error {
	return runner.RunWithStdin(ctx, args, stdout, stderr, nil)
}

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

	// Config represents the config associated with this ffx instance.
	Config *FFXConfig
	// ConfigPath is the path to the ffx config.
	ConfigPath string

	runner *subprocess.Runner
	stdout io.Writer
	stderr io.Writer
	target string
}

// NewFFXInstance creates an isolated FFXInstance.
func NewFFXInstance(
	ffxPath string,
	dir string,
	env []string,
	target, sshKey string,
	outputDir string,
) (*FFXInstance, error) {
	if ffxPath == "" {
		return nil, nil
	}
	config := newIsolatedFFXConfig(outputDir)
	config.SetJsonPointer("/target/default", target)
	sshKey, err := filepath.Abs(sshKey)
	if err != nil {
		config.Close()
		return nil, err
	}
	config.SetJsonPointer("/ssh/priv", []string{sshKey})
	config.Set("test", map[string]bool{
		"experimental_structured_output": true,
		"experimental_json_input":        true,
	})
	configPath := filepath.Join(outputDir, "ffx_config.json")
	if err := config.ToFile(configPath); err != nil {
		config.Close()
		return nil, err
	}
	env = append(env, config.Env()...)
	ffx := FFXInstanceWithConfig(ffxPath, dir, env, target, configPath)
	if ffx != nil {
		ffx.Config = config
	}
	return ffx, nil
}

func FFXInstanceWithConfig(
	ffxPath, dir string,
	env []string,
	target, configPath string,
) *FFXInstance {
	if ffxPath == "" {
		return nil
	}
	return &FFXInstance{
		ffxPath:    ffxPath,
		ConfigPath: configPath,
		runner:     &subprocess.Runner{Dir: dir, Env: append(os.Environ(), env...)},
		stdout:     os.Stdout,
		stderr:     os.Stderr,
		target:     target,
	}
}

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

// 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(level LogLevel) error {
	return f.SetConfigJsonPointer(logLevelJsonPointer, string(level))
}

// SetConfigJsonPointer sets a field in the ffx instance's associated config and
// rewrites the config file.
func (f *FFXInstance) SetConfigJsonPointer(pointer string, value interface{}) error {
	if f.Config == nil {
		config, err := configFromFile(f.ConfigPath)
		if err != nil {
			return err
		}
		f.Config = config
	}
	f.Config.SetJsonPointer(pointer, value)
	return f.Config.ToFile(f.ConfigPath)
}

// Run runs ffx with the associated config and provided args.
func (f *FFXInstance) Run(ctx context.Context, args ...string) error {
	args = append([]string{f.ffxPath, "--config", f.ConfigPath}, args...)
	if err := runCommand(ctx, f.runner, f.stdout, f.stderr, args...); err != nil {
		return fmt.Errorf("%s: %w", constants.CommandFailedMsg, err)
	}
	return nil
}

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

// Stop stops the daemon.
func (f *FFXInstance) Stop() error {
	// Use a new context for Stop() to give it time to complete.
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	err := f.Run(ctx, "daemon", "stop")
	if f.Config != nil {
		if configErr := f.Config.Close(); err == nil {
			err = configErr
		}
	}
	// Wait to see that the daemon is stopped before exiting this function
	// because the ffx command returns after it has initiated the shutdown,
	// but there may be some delay where the daemon can continue to output
	// logs before it's completely shut down.
	// TODO(fxbug.dev/92296): Remove this workaround when ffx can ensure that
	// no more logs are written once the command returns.
	for i := 0; i < 3; i++ {
		var b bytes.Buffer
		if err := runCommand(ctx, f.runner, &b, io.Discard, "pgrep", "ffx"); err != nil {
			logger.Debugf(ctx, "failed to run \"pgrep ffx\": %s", err)
			continue
		}
		if len(b.Bytes()) == 0 {
			break
		}
		logger.Debugf(ctx, "ffx daemon hasn't completed shutdown. Checking again after 1 second")
		time.Sleep(time.Second)
	}
	return err
}

// BootloaderBoot RAM boots the target.
func (f *FFXInstance) BootloaderBoot(ctx context.Context, zbi, vbmeta, slot string) error {
	var args []string
	if zbi != "" {
		args = append(args, "--zbi", zbi)
	}
	if vbmeta != "" {
		args = append(args, "--vbmeta", vbmeta)
	}
	if slot != "" {
		args = append(args, "--slot", slot)
	}
	return f.RunWithTarget(ctx, append([]string{"target", "bootloader", "boot"}, args...)...)
}

// Flash flashes the target.
func (f *FFXInstance) Flash(ctx context.Context, manifest, sshKey string) error {
	return f.RunWithTarget(ctx, "target", "flash", "--authorized-keys", sshKey, manifest)
}

// 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.RunWithTarget(
		ctx,
		append(
			[]string{
				"test",
				"run",
				"--continue-on-timeout",
				"--test-file",
				testFile,
				"--output-directory",
				testOutputDir,
			},
			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")
}
