package cli

import (
	"context"
	"fmt"
	"io"
)

// runWorkspaceDryRun inspects the local repo at resolvedPath and
// prints the file list that `vm run` / `workspace prepare` would ship
// into the guest. Runs on the CLI side (no daemon RPC needed) since
// the daemon is always local and the workspace inspection is a pure
// git read. Git calls go through d.repoInspector so tests inject a
// stub Runner via the deps struct instead of touching package globals.
func (d *deps) runWorkspaceDryRun(ctx context.Context, out io.Writer, resolvedPath, branchName, fromRef string, includeUntracked bool) error {
	spec, err := d.repoInspector.InspectRepo(ctx, resolvedPath, branchName, fromRef, includeUntracked)
	if err != nil {
		return err
	}
	fmt.Fprintf(out, "dry-run: %d file(s) would be copied to guest\n", len(spec.OverlayPaths))
	fmt.Fprintf(out, "repo: %s\n", spec.RepoRoot)
	if includeUntracked {
		fmt.Fprintln(out, "mode: tracked + untracked non-ignored (--include-untracked)")
	} else {
		fmt.Fprintln(out, "mode: tracked only (re-run with --include-untracked to also copy untracked non-ignored files)")
	}
	fmt.Fprintln(out, "---")
	for _, path := range spec.OverlayPaths {
		fmt.Fprintln(out, path)
	}
	if !includeUntracked {
		d.noteUntrackedSkipped(ctx, out, spec.RepoRoot)
	}
	return nil
}

// noteUntrackedSkipped prints a one-line notice when the repo holds
// untracked non-ignored files that will NOT be copied because
// --include-untracked was not passed.
//
// Best-effort: if sourcePath isn't inside a git repo, or git errors,
// or there are no untracked files, the helper stays silent. The
// notice is a courtesy — failing the whole operation over a courtesy
// would be worse than the notice being missing.
//
// Resolves sourcePath to the repo root internally via `git rev-parse
// --show-toplevel` so callers can pass whatever path the user typed.
// Before this helper normalised, subdir inputs ran `ls-files
// --others` scoped to the subdir, which silently underreported the
// skipped files the user needed to know about.
func (d *deps) noteUntrackedSkipped(ctx context.Context, out io.Writer, sourcePath string) {
	repoRoot, err := d.repoInspector.GitTrimmedOutput(ctx, sourcePath, "rev-parse", "--show-toplevel")
	if err != nil || repoRoot == "" {
		return
	}
	count, err := d.repoInspector.CountUntrackedPaths(ctx, repoRoot)
	if err != nil || count == 0 {
		return
	}
	fmt.Fprintf(out, "---\nnote: %d untracked non-ignored file(s) were NOT copied (git-tracked files only by default — pass --include-untracked to include them)\n", count)
}
