package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

// runGuided is what happens when somebody double-clicks the program instead of
// typing its name at a prompt.
//
// Without this, Explorer opens a console, main() finds no arguments, prints
// the usage text to stderr and exits — and Windows destroys the window in the
// same instant. From the other side of the screen that is indistinguishable
// from a crash. So when we know we were double-clicked, we ask the one
// question the program actually needs and stay on screen until the reader is
// done.
//
// This path is entered ONLY when there are no arguments and both ends of the
// program are a real console. Any scripted or piped use takes exactly the same
// code path it always did.
//
// The guided run only ever performs "scan", which reads. TraceGuard never
// deletes or changes a privacy trace even from the command line — it reports —
// so there is nothing destructive to keep out of this flow.
func runGuided() {
	in := bufio.NewScanner(os.Stdin)

	fmt.Println()
	fmt.Println("  TraceGuard")
	fmt.Println("  See what traces of your activity are sitting on this computer.")
	fmt.Println()
	fmt.Println("  It counts the browser caches, cookies, history, saved sessions,")
	fmt.Println("  thumbnails, recent-document lists, crash dumps and temporary files")
	fmt.Println("  under a folder you choose, and tells you how much space each takes")
	fmt.Println("  and how far back the oldest one goes.")
	fmt.Println()
	fmt.Println("  It only looks. Nothing is deleted, moved or changed.")
	fmt.Println()

	suggested := suggestedFolder()
	for {
		fmt.Println("  Which folder shall I look under?")
		fmt.Println("  (usually your user folder, the one with Documents and Downloads in it)")
		if suggested != "" {
			fmt.Printf("  (press Enter for %s)\n", suggested)
		}
		fmt.Print("  > ")

		if !in.Scan() {
			// stdin closed on us; there is nothing sensible left to ask.
			return
		}
		answer := strings.TrimSpace(in.Text())
		answer = strings.Trim(answer, `"`)
		if answer == "" {
			answer = suggested
		}
		if answer == "" {
			fmt.Println()
			fmt.Println("  I need a folder to look under. Try again, or close this window.")
			fmt.Println()
			continue
		}

		info, err := os.Stat(answer)
		switch {
		case err != nil:
			fmt.Println()
			fmt.Printf("  I cannot find %q.\n", answer)
			fmt.Println("  Tip: you can drag a folder from Explorer onto this window to")
			fmt.Println("  paste its location, then press Enter.")
			fmt.Println()
			continue
		case !info.IsDir():
			fmt.Println()
			fmt.Printf("  %q is a file, not a folder. Give me the folder it sits in.\n", answer)
			fmt.Println()
			continue
		}

		fmt.Println()
		fmt.Println("  Working. On a large user folder this can take a minute.")
		fmt.Println()
		cmdScan([]string{"--home", answer, "--machine", thisMachine()})
		break
	}

	fmt.Println()
	fmt.Println("  Done. Run it again any time on another folder.")
	fmt.Println("  There is a command-line version too, which can save the report as a")
	fmt.Println("  file and check a whole fleet against a policy: traceguard --help")
	pause(in)
}

// suggestedFolder offers somewhere worth looking that is certain to exist, so
// the reader can get a useful answer by pressing one key. A person's own user
// folder is where nearly every privacy trace on a Windows machine lives.
func suggestedFolder() string {
	home, err := os.UserHomeDir()
	if err != nil {
		return ""
	}
	if info, err := os.Stat(home); err != nil || !info.IsDir() {
		return ""
	}
	return home
}

// thisMachine labels the report with the computer's own name, which is what
// the reader would have typed anyway, so the guided run never has to ask.
func thisMachine() string {
	name, err := os.Hostname()
	if err != nil || strings.TrimSpace(name) == "" {
		return "this-pc"
	}
	return name
}

// pause keeps the console window open. Explorer closes it the moment the
// process exits, so without this the reader never sees the output.
func pause(in *bufio.Scanner) {
	fmt.Println()
	fmt.Print("  Press Enter to close this window. ")
	in.Scan()
}
