package main

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"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.
//
// The guided session runs the report only. DupePilot can also move the spare
// copies of a duplicate set into a quarantine folder, and this path
// deliberately never does that: somebody who double-clicked an unfamiliar
// program has not asked for their files to be moved, and cannot be shown a
// list to check first. Moving files stays on the command line.
//
// 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.
func runGuided() {
	in := bufio.NewScanner(os.Stdin)

	fmt.Println()
	fmt.Println("  DupePilot")
	fmt.Println("  Find the files you are storing more than once.")
	fmt.Println()
	fmt.Println("  Point it at a folder and it compares the files inside byte for")
	fmt.Println("  byte, then lists every set that is genuinely identical and how")
	fmt.Println("  much room you would get back by keeping one of each.")
	fmt.Println()
	fmt.Println("  This is a report and nothing else. No file is moved, changed or")
	fmt.Println("  deleted, and you are the one who decides what to do next.")
	fmt.Println()

	suggested := suggestedFolder()
	for {
		fmt.Println("  Which folder shall I check?")
		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 check. 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. Every file has to be read to be sure, so on a large")
		fmt.Println("  folder this can take a few minutes.")
		fmt.Println()
		cmdScan([]string{answer})
		break
	}

	fmt.Println()
	fmt.Println("  Done. Nothing was changed — that list is just a list.")
	fmt.Println("  The command-line version can also tidy the spare copies away into")
	fmt.Println("  a folder of your choosing: dupepilot --help")
	pause(in)
}

// suggestedFolder offers somewhere worth checking that is certain to exist, so
// the reader can get a useful answer by pressing one key.
func suggestedFolder() string {
	home, err := os.UserHomeDir()
	if err != nil {
		return ""
	}
	// A home directory is the honest default, but the same file downloaded
	// three times is the duplicate almost everybody actually has.
	for _, name := range []string{"Downloads", "Pictures"} {
		candidate := filepath.Join(home, name)
		if info, err := os.Stat(candidate); err == nil && info.IsDir() {
			return candidate
		}
	}
	return home
}

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