// Package repl implements the main event loop.
package repl

import (
	"fmt"

	"github.com/carlmjohnson/versioninfo"

	"git.lyda.ie/kevin/bulletin/dclish"
	"git.lyda.ie/kevin/bulletin/folders"
	"git.lyda.ie/kevin/bulletin/storage"
	"git.lyda.ie/kevin/bulletin/this"
)

// ActionShowFlags handles the `SHOW FLAGS` command.
func ActionShowFlags(_ *dclish.Command) error {
	flagset := false
	fmt.Printf("For the selected folder %s:\n", this.Folder.Name)
	if this.Folder.Notify != 0 {
		fmt.Println("  NOTIFY is set.")
		flagset = true
	}
	if this.Folder.Readnew != 0 {
		fmt.Println("  READNEW is set.")
		flagset = true
	}
	if this.Folder.Brief != 0 {
		fmt.Println("  BRIEF is set.")
		flagset = true
	}
	if this.Folder.Shownew != 0 {
		fmt.Println("  SHOWNEW is set.")
		flagset = true
	}
	if !flagset {
		fmt.Println("  No flags are set.")
	}
	return nil
}

// ActionShowFolder handles the `SHOW FOLDER` command.
func ActionShowFolder(cmd *dclish.Command) error {
	ctx := storage.Context()

	folder := this.Folder
	if len(cmd.Args) == 1 {
		folder = folders.FindFolder(cmd.Args[0])
	}
	if folder.Name == "" {
		fmt.Println("ERROR: Specified folder was not found.")
	}
	owners, err := this.Q.GetOwners(ctx, folder.Name)
	if err != nil || len(owners) == 0 {
		fmt.Printf("ERROR: This folder seems to lack owners (%s).\n", err)
		return nil
	}

	full := false
	if cmd.Flags["/FULL"].Value == "true" {
		// TODO: Check permissions.
		full = true
	}
	fmt.Printf("Settings for %s.\n", folder.Name)
	if full {
		switch folder.Visibility {
		case folders.FolderPublic:
			fmt.Println("  Folder is a public folder.")
		case folders.FolderSemiPrivate:
			fmt.Println("  Folder is a semi-private folder.")
		case folders.FolderPrivate:
			fmt.Println("  Folder is a private folder.")
		}
	}
	switch folder.Expire {
	case -1:
		fmt.Println("  Default expiration is permanent.")
	case 0:
		fmt.Println("  No default expiration set.")
	default:
		fmt.Printf("  Default expiration is %d days.\n", folder.Expire)
	}
	if folder.System != 0 {
		fmt.Println("  SYSTEM has been set.")
	}
	// TODO: Review SHOW_FOLDER in bulletin5.for.
	if folder.Always != 0 {
		fmt.Println("  ALWAYS has been set.")
	}
	if this.Folder.Notify != 0 {
		fmt.Println("  Default is NOTIFY.")
	}
	if this.Folder.Readnew != 0 {
		fmt.Println("  Default is READNEW.")
	}
	if this.Folder.Brief != 0 {
		fmt.Println("  Default is BRIEF.")
	}
	if this.Folder.Shownew != 0 {
		fmt.Println("  Default is SHOWNEW.")
	}

	return nil
}

// ActionShowNew handles the `SHOW NEW` command.
func ActionShowNew(_ *dclish.Command) error {
	fmt.Println("TODO: implement ActionShowNew.")
	return nil
}

// ActionShowPrivileges handles the `SHOW PRIVILEGES` command.
func ActionShowPrivileges(_ *dclish.Command) error {
	fmt.Println("TODO: implement ActionShowPrivileges.")
	return nil
}

// ActionShowUser handles the `SHOW USER` command.
func ActionShowUser(cmd *dclish.Command) error {
	showAll := false
	if cmd.Flags["/ALL"].Value == "true" {
		showAll = true
		// TODO: Check permissions.
		fmt.Println("ERROR: No privs to use command.")
		return nil
	}
	showLogin := false
	if cmd.Flags["/LOGIN"].Value == "true" {
		// TODO: Check permissions.
		showLogin = true
	}
	folder := this.Folder
	if cmd.Flags["/FOLDER"].Value != "" {
		// TODO: Check permissions.
		folder = folders.FindFolder(cmd.Flags["/FOLDER"].Value)
	}
	if cmd.Flags["/FOLDER"].Value != "" {
		since, err := ParseDate(cmd.Flags["/FOLDER"].Value)
		if err != nil {
			fmt.Println("ERROR: Invalid date specified.")
			return nil
		}
		fmt.Printf("TODO: select messages since %s.\n", since.Format("2006-05-04"))
	}
	fmt.Println("TODO: implement ActionShowUser.")
	fmt.Printf("TODO: %t %t %s.\n", showAll, showLogin, folder.Name)
	return nil
}

// ActionShowVersion handles the `SHOW VERSION` command.
func ActionShowVersion(_ *dclish.Command) error {
	rev := versioninfo.Revision
	if len(rev) > 7 {
		rev = rev[len(rev)-7:]
	}
	fmt.Printf("BULLETIN Version 2.0.7g (%s)\n", rev)
	fmt.Printf("Linked on %s\n",
		versioninfo.LastCommit.Format("2006-05-04 15:02:01"))
	return nil
}