package main

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

	"github.com/docker/docker/internal/testutil"
	"github.com/pkg/errors"
	"gotest.tools/icmd"
)

func getPrefixAndSlashFromDaemonPlatform() (prefix, slash string) {
	if testEnv.OSType == "windows" {
		return "c:", `\`
	}
	return "", "/"
}

// TODO: update code to call cmd.RunCmd directly, and remove this function
// Deprecated: use gotest.tools/icmd
func runCommandWithOutput(execCmd *exec.Cmd) (string, int, error) {
	result := icmd.RunCmd(transformCmd(execCmd))
	return result.Combined(), result.ExitCode, result.Error
}

// Temporary shim for migrating commands to the new function
func transformCmd(execCmd *exec.Cmd) icmd.Cmd {
	return icmd.Cmd{
		Command: execCmd.Args,
		Env:     execCmd.Env,
		Dir:     execCmd.Dir,
		Stdin:   execCmd.Stdin,
		Stdout:  execCmd.Stdout,
	}
}

// ParseCgroupPaths parses 'procCgroupData', which is output of '/proc/<pid>/cgroup', and returns
// a map which cgroup name as key and path as value.
func ParseCgroupPaths(procCgroupData string) map[string]string {
	cgroupPaths := map[string]string{}
	for _, line := range strings.Split(procCgroupData, "\n") {
		parts := strings.Split(line, ":")
		if len(parts) != 3 {
			continue
		}
		cgroupPaths[parts[1]] = parts[2]
	}
	return cgroupPaths
}

// RandomTmpDirPath provides a temporary path with rand string appended.
// does not create or checks if it exists.
func RandomTmpDirPath(s string, platform string) string {
	// TODO: why doesn't this use os.TempDir() ?
	tmp := "/tmp"
	if platform == "windows" {
		tmp = os.Getenv("TEMP")
	}
	path := filepath.Join(tmp, fmt.Sprintf("%s.%s", s, testutil.GenerateRandomAlphaOnlyString(10)))
	if platform == "windows" {
		return filepath.FromSlash(path) // Using \
	}
	return filepath.ToSlash(path) // Using /
}

// RunCommandPipelineWithOutput runs the array of commands with the output
// of each pipelined with the following (like cmd1 | cmd2 | cmd3 would do).
// It returns the final output, the exitCode different from 0 and the error
// if something bad happened.
// Deprecated: use icmd instead
func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, err error) {
	if len(cmds) < 2 {
		return "", errors.New("pipeline does not have multiple cmds")
	}

	// connect stdin of each cmd to stdout pipe of previous cmd
	for i, cmd := range cmds {
		if i > 0 {
			prevCmd := cmds[i-1]
			cmd.Stdin, err = prevCmd.StdoutPipe()

			if err != nil {
				return "", fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
			}
		}
	}

	// start all cmds except the last
	for _, cmd := range cmds[:len(cmds)-1] {
		if err = cmd.Start(); err != nil {
			return "", fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
		}
	}

	defer func() {
		var pipeErrMsgs []string
		// wait all cmds except the last to release their resources
		for _, cmd := range cmds[:len(cmds)-1] {
			if pipeErr := cmd.Wait(); pipeErr != nil {
				pipeErrMsgs = append(pipeErrMsgs, fmt.Sprintf("command %s failed with error: %v", cmd.Path, pipeErr))
			}
		}
		if len(pipeErrMsgs) > 0 && err == nil {
			err = fmt.Errorf("pipelineError from Wait: %v", strings.Join(pipeErrMsgs, ", "))
		}
	}()

	// wait on last cmd
	out, err := cmds[len(cmds)-1].CombinedOutput()
	return string(out), err
}

type elementListOptions struct {
	element, format string
}

func existingElements(c *testing.T, opts elementListOptions) []string {
	var args []string
	switch opts.element {
	case "container":
		args = append(args, "ps", "-a")
	case "image":
		args = append(args, "images", "-a")
	case "network":
		args = append(args, "network", "ls")
	case "plugin":
		args = append(args, "plugin", "ls")
	case "volume":
		args = append(args, "volume", "ls")
	}
	if opts.format != "" {
		args = append(args, "--format", opts.format)
	}
	out, _ := dockerCmd(c, args...)
	var lines []string
	for _, l := range strings.Split(out, "\n") {
		if l != "" {
			lines = append(lines, l)
		}
	}
	return lines
}

// ExistingContainerIDs returns a list of currently existing container IDs.
func ExistingContainerIDs(c *testing.T) []string {
	return existingElements(c, elementListOptions{element: "container", format: "{{.ID}}"})
}

// ExistingContainerNames returns a list of existing container names.
func ExistingContainerNames(c *testing.T) []string {
	return existingElements(c, elementListOptions{element: "container", format: "{{.Names}}"})
}

// RemoveLinesForExistingElements removes existing elements from the output of a
// docker command.
// This function takes an output []string and returns a []string.
func RemoveLinesForExistingElements(output, existing []string) []string {
	for _, e := range existing {
		index := -1
		for i, line := range output {
			if strings.Contains(line, e) {
				index = i
				break
			}
		}
		if index != -1 {
			output = append(output[:index], output[index+1:]...)
		}
	}
	return output
}

// RemoveOutputForExistingElements removes existing elements from the output of
// a docker command.
// This function takes an output string and returns a string.
func RemoveOutputForExistingElements(output string, existing []string) string {
	res := RemoveLinesForExistingElements(strings.Split(output, "\n"), existing)
	return strings.Join(res, "\n")
}
