package main

import (
	"errors"
	"fmt"
	"io"
	"strings"
)

const (
	interactiveCommandHelp = "help"
	interactiveCommandQuit = "quit"
	interactiveCommandText = "text"
	interactiveCommandFile = "file"
)

// 交互式命令行界面，允许用户在连接建立后反复发送文本或文件消息。
var errEmptyInteractiveCommand = errors.New("interactive command is empty")

type interactiveCommand struct {
	name  string
	to    string
	value string
}

// 解析用户输入的交互式命令，支持发送文本或文件消息，以及查看帮助和退出。
func parseInteractiveCommand(line string) (interactiveCommand, error) {
	commandName, rest, ok := cutInteractiveField(strings.TrimSpace(line))
	if !ok {
		return interactiveCommand{}, errEmptyInteractiveCommand
	}

	switch strings.ToLower(commandName) {
	case "help", "h", "?":
		return interactiveCommand{name: interactiveCommandHelp}, nil
	case "quit", "exit":
		return interactiveCommand{name: interactiveCommandQuit}, nil
	case interactiveCommandText:
		to, body, err := parseInteractiveTargetValue(rest, interactiveCommandText)
		if err != nil {
			return interactiveCommand{}, err
		}
		return interactiveCommand{name: interactiveCommandText, to: to, value: body}, nil
	case interactiveCommandFile:
		to, path, err := parseInteractiveTargetValue(rest, interactiveCommandFile)
		if err != nil {
			return interactiveCommand{}, err
		}
		return interactiveCommand{name: interactiveCommandFile, to: to, value: path}, nil
	default:
		return interactiveCommand{}, fmt.Errorf("unknown command %q; type help for usage", commandName)
	}
}

func parseInteractiveTargetValue(rest, commandName string) (string, string, error) {
	to, value, ok := cutInteractiveField(strings.TrimSpace(rest))
	if !ok {
		return "", "", fmt.Errorf("%s command requires a target peer and payload", commandName)
	}
	if strings.TrimSpace(value) == "" {
		return "", "", fmt.Errorf("%s command requires a non-empty payload", commandName)
	}

	return to, strings.TrimSpace(value), nil
}

func cutInteractiveField(input string) (string, string, bool) {
	trimmed := strings.TrimSpace(input)
	if trimmed == "" {
		return "", "", false
	}

	for i, r := range trimmed {
		if r == ' ' || r == '\t' {
			return trimmed[:i], strings.TrimSpace(trimmed[i+1:]), true
		}
	}

	return trimmed, "", true
}

// 打印交互式命令帮助信息，列出可用的命令和用法说明。
func printInteractiveHelp(w io.Writer) {
	_, _ = fmt.Fprintln(w, "interactive mode commands:")
	_, _ = fmt.Fprintln(w, "  help                    show this help")
	_, _ = fmt.Fprintln(w, "  text <peer> <message>   send one text message over the existing connection")
	_, _ = fmt.Fprintln(w, "  file <peer> <path>      send one file over the existing connection")
	_, _ = fmt.Fprintln(w, "  quit                    exit this peer process")
}
