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. DuplicateDeck can also move the
// non-keepers of a cluster into a quarantine folder, and this path
// deliberately never does that. A name match is a hint rather than proof —
// the README's own warning about camera filenames says so — and somebody who
// double-clicked an unfamiliar program has had no chance to read the list
// 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("  DuplicateDeck")
	fmt.Println("  Find the files you have saved twice under slightly different names.")
	fmt.Println()
	fmt.Println("  invoice.pdf, invoice (1).pdf, invoice_final.pdf and")
	fmt.Println("  invoice - Copy.pdf are one document to you. DuplicateDeck reads")
	fmt.Println("  the names, groups the ones that belong together, and suggests")
	fmt.Println("  which of each group is worth keeping.")
	fmt.Println()
	fmt.Println("  It only reads names, sizes and dates. Nothing is opened, moved,")
	fmt.Println("  changed or deleted.")
	fmt.Println()

	suggested := suggestedFolder()
	for {
		fmt.Println("  Which folder shall I look at?")
		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 at. 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 folder with a lot of files this can take a minute.")
		fmt.Println()
		cmdScan([]string{answer})
		break
	}

	fmt.Println()
	fmt.Println("  Done. Nothing was changed — that list is just a list.")
	fmt.Println("  Read it carefully before you act on it: photos straight off a")
	fmt.Println("  camera get names like IMG_4471 and IMG_4472, which look alike to")
	fmt.Println("  this program but are two different pictures.")
	fmt.Println("  There is a command-line version too: duplicatedeck --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.
func suggestedFolder() string {
	home, err := os.UserHomeDir()
	if err != nil {
		return ""
	}
	// A home directory is the honest default, but "invoice (1).pdf" next to
	// "invoice.pdf" is what a downloads folder is made of.
	for _, name := range []string{"Downloads", "Documents"} {
		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()
}
