package main

import (
	"flag"
	"log"

	"github.com/stvp/rollbar"
	"github.com/zenazn/goji"

	"code.justin.tv/release/libforerunner"
	"code.justin.tv/video/spectre/api"
	"code.justin.tv/video/spectre/auth"
	"code.justin.tv/video/spectre/backend"
	"code.justin.tv/video/spectre/monitor"
	"code.justin.tv/video/spectre/playhead"
	"code.justin.tv/video/spectre/util"
	"github.com/zenazn/goji/graceful"

	"code.justin.tv/common/goauthorization"
	"code.justin.tv/common/meh-restart/restart"
)

var (
	// GitCommit is set at build time to the current git commit for the project.
	GitCommit = "production"
	c         *config
	fr        *libforerunner.Forerunner
)

type config struct {
	ConsulPrefix string `description:"Prefix for consul data storage"`
	Environment  string `description:"Environment spectre is running in"`
	PgConnInfo   string `description:"Connection string for postgres"`
	Port         int    `description:"Port to bind to for HTTP API"`
	RollbarToken string `forerunner:",secret" description:"Token for talking to rollbar"`
	StatsdHost   string `description:"Host to send statsd data to"`
	StatsdPort   int    `description:"Port to send statsd data to"`
	StatsdPrefix string `description:"Prefix for statsd metrics"`
}

func main() {

	monitorFlag := flag.Bool("monitor", false, "Only run the Spectre Monitor")
	monitor.RegisterFlags()

	// Setup the default configuration
	c = &config{
		ConsulPrefix: "settings/spectre/production",
		Environment:  "production",
		PgConnInfo:   "host=spectre-production.cbywgl1h5pos.us-west-2.rds.amazonaws.com port=5432 user=spectre password=vwiehrpiacnldmn sslmode=disable",
		Port:         8080,
		RollbarToken: "804eeafa0ace435caf14950e81fd9472",
		StatsdHost:   "graphite.internal.justin.tv",
		StatsdPort:   8125,
		StatsdPrefix: "spectre.production",
	}
	fr, err := libforerunner.Init(&libforerunner.Options{
		DefaultConfig: c,
	})
	if err != nil {
		panic(err)
	}
	if err = fr.GetConfig(c); err != nil {
		panic(err)
	}

	// Configure Rollbar
	rollbar.Token = c.RollbarToken
	rollbar.Environment = c.Environment
	rollbar.CodeVersion = GitCommit

	backend := backend.NewBackend(c.PgConnInfo)
	go backend.CacheAllChannels()
	util.MustSetupStatsd(c.StatsdHost, c.StatsdPort, c.StatsdPrefix)

	if *monitorFlag {
		monitor.Monitor(backend)
		return
	}

	authHandler := auth.NewHandler("auth/rails_key.pub")

	// InitializeDecoder(private-key-path, token-audience, token-issuer)
	goauthorization.InitializeDecoder("auth/cartman_key.pub", "code.justin.tv/video/spectre", "code.justin.tv/web/cartman")

	api.NewRouter(backend, util.Stats, authHandler)

	playhead.Backend = backend
	playhead.Sync(backend)

	restart.OnShutdown(func() {
		log.Println("Shutting down")
		graceful.Shutdown()
	})

	port := ":80"
	if f := flag.Lookup("bind"); f != nil {
		port = f.Value.String()
	}

	api.Running = true
	err = graceful.ListenAndServe(port, goji.DefaultMux)
	if err != nil {
		log.Fatalln("server error:", err)
	}

	log.Println("No longer listening. Waiting for pending requests to finish")

	graceful.Wait()
	log.Println("Exiting")
}
