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.
//
// 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.
//
// Guided mode runs "inventory" and nothing else. The transfer command writes
// to the new phone and is deliberately not offered here, in any form.
func runGuided() {
	in := bufio.NewScanner(os.Stdin)

	fmt.Println()
	fmt.Println("  MovePhone")
	fmt.Println("  Look at everything on an old phone before you move it to a new one.")
	fmt.Println()
	fmt.Println("  Plug the phone in, let Windows give it a drive letter, and point this")
	fmt.Println("  at its folder. Every file is identified by what it actually is rather")
	fmt.Println("  than by its name, so you get an honest count of photos, videos,")
	fmt.Println("  music and documents — and how much of it is duplicated.")
	fmt.Println()
	fmt.Println("  It only reads. Nothing is copied, changed or deleted.")
	fmt.Println()

	folder, ok := askFolder(in)
	if !ok {
		return
	}

	fmt.Println()
	fmt.Println("  Working. Every file is read and fingerprinted, so a full phone takes")
	fmt.Println("  a few minutes.")
	fmt.Println()
	cmdInventory([]string{"--src", folder})

	fmt.Println()
	fmt.Println("  Done. Nothing on the phone was touched.")
	fmt.Println("  The command-line version can also plan and carry out the move to a")
	fmt.Println("  new phone, checking every file as it goes: movephone --help")
	pause(in)
}

// askFolder asks where the old phone's files are and keeps asking until the
// answer is a folder that really exists. It reports false only when stdin
// closes, at which point there is nothing sensible left to ask.
func askFolder(in *bufio.Scanner) (string, bool) {
	suggested := suggestedFolder()
	for {
		fmt.Println("  Where are the old phone's files?")
		if suggested != "" {
			fmt.Printf("  (press Enter for %s)\n", suggested)
		}
		fmt.Println("  Tip: you can drag the phone's folder from Explorer onto this")
		fmt.Println("  window to paste its location.")
		fmt.Print("  > ")

		if !in.Scan() {
			return "", false
		}
		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("  If the phone is plugged in, open it in Explorer first so")
			fmt.Println("  Windows gives it a drive letter, then drag it onto this window.")
			fmt.Println()
			continue
		case !info.IsDir():
			fmt.Println()
			fmt.Printf("  %q is a single file, not a folder. Give me the folder it sits\n", answer)
			fmt.Println("  in and I will look at everything inside.")
			fmt.Println()
			continue
		}
		return answer, true
	}
}

// suggestedFolder offers somewhere that is certain to exist, so the reader can
// get a useful answer by pressing one key. A phone appears under its own drive
// letter, which nothing can guess, so this is only a starting point.
func suggestedFolder() string {
	home, err := os.UserHomeDir()
	if err != nil {
		return ""
	}
	for _, name := range []string{"Pictures", "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()
}
