package main

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

// runGuided is what happens when somebody double-clicks ClipStudio instead of
// typing its name at a prompt.
//
// Explorer opens a console, runs the program with no arguments, and destroys
// the window the instant the process exits — so printing usage and quitting
// looks exactly like a crash. When we know we were double-clicked we ask the
// one thing ClipStudio needs and stay on screen until the reader is done.
//
// The guided session only ever READS the recordings. It reports the passwords
// and keys it found, with every secret masked in the report itself. Writing
// redacted copies, and archiving old clips, stay on the command line where the
// operator names the output and asks for it deliberately.
func runGuided() {
	in := bufio.NewScanner(os.Stdin)

	fmt.Println()
	fmt.Println("  ClipStudio")
	fmt.Println("  Check your screen recordings for passwords before you share them.")
	fmt.Println()
	fmt.Println("  A terminal recording is plain text. If somebody typed a password or")
	fmt.Println("  pasted an access key while recording, it is sitting in the file.")
	fmt.Println("  Point me at the folder your recordings live in and I will read them")
	fmt.Println("  back and tell you which ones have something in them they should not.")
	fmt.Println()
	fmt.Println("  Whatever I find is shown masked, never in full. Your recordings are")
	fmt.Println("  only read — nothing is changed, moved or deleted.")
	fmt.Println()

	suggested := suggestedLibrary()
	for {
		fmt.Println("  Which folder holds your recordings?")
		if suggested != "" {
			fmt.Printf("  (press Enter for %s)\n", suggested)
		}
		fmt.Println("  Tip: you can drag a folder from Explorer onto this window to")
		fmt.Println("  paste its location, then press Enter.")
		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 in. 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()
			continue
		case !info.IsDir():
			fmt.Println()
			fmt.Printf("  %q is a file, not a folder. Give me the folder it sits in and\n", answer)
			fmt.Println("  I will check everything in there.")
			fmt.Println()
			continue
		}

		// Checked here rather than left to the scan: an empty library is an
		// ordinary mistake, and the reader deserves another try at it instead
		// of an error and a closed window.
		clips, err := collectCasts(answer)
		if err != nil {
			fmt.Println()
			fmt.Printf("  I could not read that folder: %v\n", err)
			fmt.Println()
			continue
		}
		if len(clips) == 0 {
			fmt.Println()
			fmt.Printf("  There are no recordings in %s.\n", answer)
			fmt.Println("  I am looking for SessionForge recordings — files ending in")
			fmt.Println("  .jsonl or .cast. Try the folder your recorder saves into.")
			fmt.Println()
			continue
		}

		fmt.Println()
		fmt.Printf("  Found %d %s. Reading them back — a long recording takes a moment.\n",
			len(clips), plural(len(clips), "recording", "recordings"))
		fmt.Println()
		cmdScan([]string{"--lib", answer})
		break
	}

	fmt.Println()
	fmt.Println("  Done. Every recording you gave me is untouched: this was a read.")
	fmt.Println("  Writing a safe, masked copy of a recording you can share, and")
	fmt.Println("  archiving old clips, are separate command-line steps — and ClipStudio")
	fmt.Println("  never deletes a recording in any of them. Run clipstudio --help.")
	pause(in)
}

// plural picks the right word for a count, so the report reads like English.
func plural(n int, one, many string) string {
	if n == 1 {
		return one
	}
	return many
}

// suggestedLibrary offers a folder of recordings the reader can accept with
// one keypress: the obvious one beside the program, in the folder the console
// opened in, or under their home. It returns "" when there is no such folder,
// and the prompt copes with that.
func suggestedLibrary() string {
	var dirs []string
	if exe, err := os.Executable(); err == nil {
		dirs = append(dirs, filepath.Dir(exe))
	}
	if wd, err := os.Getwd(); err == nil {
		dirs = append(dirs, wd)
	}
	if home, err := os.UserHomeDir(); err == nil {
		dirs = append(dirs, home, filepath.Join(home, "Videos"), filepath.Join(home, "Documents"))
	}
	for _, dir := range dirs {
		for _, name := range []string{"clips", "recordings", "casts"} {
			candidate := filepath.Join(dir, name)
			if info, err := os.Stat(candidate); err == nil && info.IsDir() {
				return candidate
			}
		}
	}
	return ""
}

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