package cli

import (
	"context"
	"fmt"
	"os/exec"
)

func extractPrompt(input map[string]any) string {
	if input == nil {
		return ""
	}
	if v, ok := input["prompt"]; ok {
		if s, ok := v.(string); ok {
			return s
		}
	}
	return fmt.Sprintf("%v", input)
}

func applyCmdWorkspace(cmd *exec.Cmd, workspace string) error {
	dir, err := prepareWorkspaceDir(workspace)
	if err != nil {
		return err
	}
	if dir != "" {
		cmd.Dir = dir
	}
	return nil
}

func applyCmdEnv(cmd *exec.Cmd, env []string) {
	if len(env) > 0 {
		cmd.Env = append(cmd.Environ(), env...)
	}
}

// buildCmd applies workspace before env, preserving the pre-refactor
// dir-before-env order for the context one-shot lifecycle so cmd.Environ()
// picks up PWD=<workspace> when env overrides are present.
func buildCmd(ctx context.Context, command string, args []string, env []string, workspace string) (*exec.Cmd, error) {
	cmd := exec.CommandContext(ctx, command, args...)
	if err := applyCmdWorkspace(cmd, workspace); err != nil {
		return nil, err
	}
	applyCmdEnv(cmd, env)
	return cmd, nil
}

// buildCmdWithoutContext applies env before workspace, preserving the
// pre-refactor env-before-dir order for the codex app-server, opencode
// local server, and non-terminal persistent lifecycles so cmd.Environ()
// keeps the parent PWD instead of being overridden to match workspace.
func buildCmdWithoutContext(command string, args []string, env []string, workspace string) (*exec.Cmd, error) {
	cmd := exec.Command(command, args...)
	applyCmdEnv(cmd, env)
	if err := applyCmdWorkspace(cmd, workspace); err != nil {
		return nil, err
	}
	return cmd, nil
}
