package main

import (
	"context"
	"crypto/tls"
	"flag"
	"log"
	"math/rand"
	"net"
	"strings"
	"time"

	"github.com/fluffle/goirc/client"
	"github.com/tcolgate/hugot"
	"github.com/tcolgate/hugot/adapters/irc"

	"ur.gs/lysenko/adapters"
	"ur.gs/lysenko/handlers/deadline"
	"ur.gs/lysenko/handlers/quotedb"
)

var (
	channels = flag.String("channels", "##testing,##test", "Channels to join (separated by comma)")
	host     = flag.String("host", "chat.freenode.net", "Server host[:port]")
	ident    = flag.String("ident", "lysenko", "Lysenko Bot")
	nick     = flag.String("nick", "lysenko", "Lysenko Bot")
	nickserv = flag.String("nickserv", "", "NickServ password")
	quotes   = flag.String("quotedb", ":memory:", "sqlite3 quote database")
	ssl      = flag.Bool("ssl", true, "Enable SSL")
	testmode = flag.Bool("testmode", false, "Use STDIN/STDOUT instead of IRC for messages")
)

func init() {
	// TODO: better rand.Seed
	rand.Seed(time.Now().Unix())
}

func ircAdapter() hugot.Adapter {
	channelList := strings.Split(*channels, ",")

	config := client.NewConfig(*nick, "lysenko", "Comrade Trofim Lysenko")
	config.Server = *host
	config.Pass = *nickserv
	config.SSL = *ssl

	if config.SSL {
		hostname, _, err := net.SplitHostPort(config.Server)
		if err != nil {
			log.Fatal(err)
		}
		config.SSLConfig = &tls.Config{
			ServerName: hostname,
		}
	}

	return irc.New(config, channelList...)
}

func main() {
	flag.Parse()

	adapter := adapters.NewPrefixAdapter(ircAdapter(), "!")
	adapter.PrivateHelpOnly = true

	ctx := context.Background()
	go adapter.Run(ctx)

	db, err := quotedb.New(*quotes)
	if err != nil {
		log.Fatal(err)
	}
	defer db.DB.Close()

	mux := hugot.DefaultMux
	mux.HandleHears(&quotedb.AddQuoteHandler{QuoteDB: db})
	mux.HandleHears(deadline.NewHears(&quotedb.LastQuoteHandler{QuoteDB: db}))
	mux.HandleHears(deadline.NewHears(&quotedb.FindQuoteHandler{QuoteDB: db}))
	mux.HandleHears(deadline.NewHears(&quotedb.RandQuoteHandler{QuoteDB: db}))
	mux.HandleHears(deadline.NewHears(&quotedb.QuoteHandler{QuoteDB: db}))

	hugot.ListenAndServe(ctx, mux, adapter)
}
