package cmd

import (
	"fmt"
	"log"
	"os"

	"github.com/Jaculabilis/intake/core"
	"github.com/spf13/cobra"
)

var channelCmd = &cobra.Command{
	Use:     "channel --channel name {--add source | --remove source | --delete [-y]}",
	GroupID: sourceGroup.ID,
	Short:   "Manage channels",
	Long: `A channel is a group of sources that can be viewed together. Adding a source
to a channel creates it and removing all sources from a channel deletes it.
`,
	Run: func(cmd *cobra.Command, args []string) {
		channel(
			stringArg(cmd, "channel"),
			stringArg(cmd, "add"),
			stringArg(cmd, "remove"),
			boolArg(cmd, "delete"),
			boolArg(cmd, "yes"),
		)
	},
	DisableFlagsInUseLine: true,
}

func init() {
	rootCmd.AddCommand(channelCmd)

	channelCmd.Flags().StringP("channel", "c", "", "Channel to operate on")
	channelCmd.Flags().String("add", "", "Add a source to a channel")
	channelCmd.Flags().String("remove", "", "Remove a source from a channel")
	channelCmd.Flags().Bool("delete", false, "Delete a channel")
	channelCmd.Flags().BoolP("yes", "y", false, "Do not ask for confirmation")
	channelCmd.MarkFlagsMutuallyExclusive("add", "remove", "delete")
	channelCmd.MarkFlagsOneRequired("add", "remove", "delete")
}

func channel(channel, add, remove string, delete bool, yes bool) {
	if channel == "" {
		log.Fatal("error: --channel is empty")
	}

	db := openAndMigrateDb()

	if delete {
		channelSources, err := core.GetSourcesInChannel(db)
		if err != nil {
			log.Fatalf("error: failed to get sources in channel: %s", err)
		}
		sources, ok := channelSources[channel]
		if !ok {
			log.Fatalf("error: channel %s does not exist", channel)
		}
		if !yes {
			var response string
			fmt.Printf("Are you sure you want to delete channel %s? (y/N): ", channel)
			_, err := fmt.Scanln(&response)
			if err != nil || (response != "y" && response != "Y") {
				os.Exit(1)
			}
		}
		for _, source := range sources {
			if err := core.DeleteSourceFromChannel(db, channel, source); err != nil {
				log.Fatalf("error: failed to remove source from channel: %v", err)
			}
		}
		log.Printf("Removed all sources from channel %s", channel)
	} else if add != "" {
		if err := core.AddSourceToChannel(db, channel, add); err != nil {
			log.Fatalf("error: failed to add source to channel: %v", err)
		}
		log.Printf("Added source %s to channel %s", add, channel)
	} else if remove != "" {
		if err := core.DeleteSourceFromChannel(db, channel, remove); err != nil {
			log.Fatalf("error: failed to remove source from channel: %v", err)
		}
		log.Printf("Removed source %s from channel %s", remove, channel)
	}
}