package main

import (
	"context"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"flag"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"sync"
	"time"

	"github.com/boltdb/bolt"
	oidc "github.com/coreos/go-oidc"
	"github.com/golang/glog"
	"github.com/gorilla/sessions"
	"golang.org/x/oauth2"
)

var (
	flagSOAPAddress       string
	flagSOAPUsername      string
	flagSOAPPassword      string
	flagListen            string
	flagSecret            string
	flagOAuthClientID     string
	flagOAuthClientSecret string
	flagOAuthRedirectURL  string
	flagDB                string
	flagMOTD              string
)

func init() {
	flag.Set("logtostderr", "true")
}

func main() {
	flag.StringVar(&flagSOAPAddress, "soap_address", "http://127.0.0.1:7878", "Address of AC SOAP server")
	flag.StringVar(&flagSOAPUsername, "soap_username", "test1", "SOAP username")
	flag.StringVar(&flagSOAPPassword, "soap_password", "", "SOAP password")
	flag.StringVar(&flagListen, "listen", "127.0.0.1:8080", "HTTP listen address")
	flag.StringVar(&flagSecret, "secret", "", "Cookie secret")
	flag.StringVar(&flagOAuthClientID, "oauth_client_id", "", "OAuth client ID")
	flag.StringVar(&flagOAuthClientSecret, "oauth_client_secret", "", "OAuth client secret")
	flag.StringVar(&flagOAuthRedirectURL, "oauth_redirect_url", "", "OAuth redirect URL")
	flag.StringVar(&flagDB, "db", "db.db", "Path to database")
	flag.StringVar(&flagMOTD, "motd", "", "Path to MOTD")
	flag.Parse()

	if flagSecret == "" {
		glog.Exitf("-secret must be set")
	}

	var err error
	var motd []byte
	if flagMOTD == "" {
		glog.Warningf("no MOTD defined, set -motd to get one")
	} else {
		motd, err = ioutil.ReadFile(flagMOTD)
		if err != nil {
			glog.Exitf("cannot read MOTD %q: %v", flagMOTD, err)
		}
	}

	db, err := bolt.Open(flagDB, 0600, nil)
	if err != nil {
		glog.Exitf("opening database failed: %v", err)
	}

	provider, err := oidc.NewProvider(context.Background(), "https://sso.hackerspace.pl")
	if err != nil {
		glog.Exitf("newprovider: %v", err)
	}
	oauth2Config := oauth2.Config{
		ClientID:     flagOAuthClientID,
		ClientSecret: flagOAuthClientSecret,
		RedirectURL:  flagOAuthRedirectURL,

		// Discovery returns the OAuth2 endpoints.
		Endpoint: provider.Endpoint(),

		// "openid" is a required scope for OpenID Connect flows.
		Scopes: []string{oidc.ScopeOpenID, "profile:read"},
	}

	err = db.Update(func(tx *bolt.Tx) error {
		for _, name := range []string{
			"emailToAccount",
		} {
			_, err := tx.CreateBucketIfNotExists([]byte(name))
			if err != nil {
				return fmt.Errorf("create bucket %q: %s", name, err)
			}
		}
		return nil
	})
	if err != nil {
		glog.Exitf("db setup failed: %v", err)
	}

	s := &server{
		db:     db,
		store:  sessions.NewCookieStore([]byte(flagSecret)),
		oauth2: &oauth2Config,
		motd:   string(motd),
	}

	http.HandleFunc("/", s.viewIndex)
	http.HandleFunc("/login", s.viewLogin)
	http.HandleFunc("/oauth", s.viewOauth)
	http.HandleFunc("/callback", s.viewOauthCallback)
	http.HandleFunc("/setup", s.viewOauthSetup)
	http.HandleFunc("/reset", s.viewReset)
	http.HandleFunc("/logout", s.viewLogout)
	http.HandleFunc("/spaceapi", s.viewSpaceAPI)

	err = http.ListenAndServe(flagListen, nil)
	if err != nil {
		glog.Exitf("ListenAndServe: %v", err)
	}
}

type server struct {
	db     *bolt.DB
	store  *sessions.CookieStore
	oauth2 *oauth2.Config
	motd   string

	onlineLock     sync.RWMutex
	onlineData     []playerinfo
	onlineDeadline time.Time
}

var (
	tLogin = template.Must(template.New("login").Parse(`<html>
<title>super wow - who are you?</title>
<body>
<pre>

 ___ _   _ _ __   ___ _ __  __      _______      __
/ __| | | | '_ \ / _ \ '__| \ \ /\ / / _ \ \ /\ / /
\__ \ |_| | |_) |  __/ |     \ V  V / (_) \ V  V /
|___/\__,_| .__/ \___|_|      \_/\_/ \___/ \_/\_/
          |_|
 _         _       _             _           _       _
| | _____ | | ___ (_)___ _ _ __ | | _____   | |_   _| |__
| |/ / _ \| |/ _ \_  / _' | '_ \| |/ / _ \  | | | | | '_ \
|   < (_) | |  __// / (_| | | | |   < (_) | | | |_| | |_) |
|_|\_\___/|_|\___/___\__,_|_| |_|_|\_\___/  |_|\__,_|_.__/

 _         _                    __
| | _____ | | ___  __ _  ___    \ \
| |/ / _ \| |/ _ \/ _' |/ _ \  (_) |
|   < (_) | |  __/ (_| | (_) |  _| |
|_|\_\___/|_|\___|\__, |\___/  (_) |
                  |___/         /_/

</pre>
<a href="/oauth">Sign in (or create new account) with HSWAW SSO</a>.<br/>

<p>
Not a hswaw member? Talk to q3k.
</p>
</body>`))
	tSetup = template.Must(template.New("setup").Parse(`<html>
<title>super wow - setup account</title>
<body>
<b>hi, please provide details for your new WoW account</b><br/>
pick any username you want, pick a 3-16 character password that isn't the same as your sso password (duh)<br />
(this isn't your character name, this will only be used to log into WoW)
{{ if .Error }}
<br /><b>error</b>: {{ .Error }}<br />
{{ end }}
<form method="post" action="/setup">
username:<input name="username" value={{ .Username }}></input><br/>
password:<input name="password" type="password"></input><br/>
<input type=submit value="create account"/>
</form>
</body>`))
	tIndex = template.Must(template.New("index").Parse(`<html>
<title>super wow</title>
<style type="text/css">
    body {
        background-color: #fff;
    }
    table, th, td {
        background-color: #eee;
        padding: 0.2em 0.4em 0.2em 0.4em;
    }
    table th {
        background-color: #c0c0c0;
    }
    table {
        background-color: #fff;
        border-spacing: 0.2em;
    }
</style>
<body>
<b>Hello, {{ .Username }}.</b></br>
<a href="/logout">Log out.</a><br />
{{ .MOTD }}
<p>
Your account name is {{ .Username }}. Use the password that you entered when logging in via SSO for the first time, or <form action="/reset" method="POST"><input name="password" type="password" /><input type="submit" value="set a new password"/>.</form>
</p>
<b>Currently in-game:</b>
<table>
<tr><th>Account</th><th>Character</th></tr>
{{ range .Online }}
<tr><td>{{ .Account }}</td><td>{{ .Character }}</td></tr>
{{ end }}
</table>
</body>`))
)

func (s *server) session(r *http.Request) *sessions.Session {
	session, _ := s.store.Get(r, sessionName)
	return session
}

func (s *server) sessionGet(r *http.Request, k string) string {
	v, ok := s.session(r).Values[k]
	if !ok {
		return ""
	}
	v2, ok := v.(string)
	if !ok {
		return ""
	}
	return v2
}

func (s *server) sessionPut(w http.ResponseWriter, r *http.Request, k, v string) {
	session := s.session(r)
	session.Values[k] = v
	session.Save(r, w)
}

func (s *server) online(ctx context.Context) []playerinfo {
	s.onlineLock.RLock()
	if s.onlineData == nil || time.Now().After(s.onlineDeadline) {
		s.onlineLock.RUnlock()
		s.onlineLock.Lock()
		data, err := onlinelist(ctx)
		if err != nil {
			glog.Errorf("onlinelist fatch failed: %v", err)
			s.onlineDeadline = time.Now().Add(10 * time.Second)
		} else {
			s.onlineData = data
			s.onlineDeadline = time.Now().Add(60 * time.Second)
		}
		s.onlineLock.Unlock()
		s.onlineLock.RLock()
	}

	res := make([]playerinfo, len(s.onlineData))
	for i, pi := range s.onlineData {
		res[i] = pi
	}
	s.onlineLock.RUnlock()
	return res
}

func (s *server) viewIndex(w http.ResponseWriter, r *http.Request) {
	account := s.sessionGet(r, "account")
	if account == "" {
		http.Redirect(w, r, "/login", 302)
		return
	}
	err := tIndex.Execute(w, map[string]interface{}{
		"Username": account,
		"Online":   s.online(r.Context()),
		"MOTD":     template.HTML(s.motd),
	})
	if err != nil {
		glog.Errorf("/: %v", err)
		return
	}
}

const sessionName = "wow"

func (s *server) viewLogin(w http.ResponseWriter, r *http.Request) {
	account := s.sessionGet(r, "account")
	if account != "" {
		http.Redirect(w, r, "/", 302)
		return
	}
	err := tLogin.Execute(w, nil)
	if err != nil {
		glog.Errorf("/login: %v", err)
		return
	}
}

func (s *server) viewOauth(w http.ResponseWriter, r *http.Request) {
	stateBytes := make([]byte, 8)
	_, err := rand.Read(stateBytes)
	if err != nil {
		glog.Errorf("/oauth: random: %v", err)
		return
	}
	state := hex.EncodeToString(stateBytes)
	s.sessionPut(w, r, "ostate", state)
	url := s.oauth2.AuthCodeURL(state)
	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}

func (s *server) viewOauthCallback(w http.ResponseWriter, r *http.Request) {
	if r.FormValue("errors") != "" {
		fmt.Fprintf(w, "Errors: %s", r.FormValue("errors"))
		return
	}
	state := s.sessionGet(r, "ostate")
	if state == "" {
		glog.Errorf("No state")
		http.Redirect(w, r, "/", 302)
		return
	}
	if state != r.FormValue("state") {
		glog.Errorf("Invalid state")
		http.Redirect(w, r, "/", 302)
		return
	}
	oauth2Token, err := s.oauth2.Exchange(r.Context(), r.FormValue("code"))
	if err != nil {
		glog.Errorf("Exchange failed: %v", err)
		http.Redirect(w, r, "/", 302)
		return
	}
	client := s.oauth2.Client(r.Context(), oauth2Token)
	res, err := client.Get("https://sso.hackerspace.pl/api/1/userinfo")
	if err != nil {
		glog.Errorf("Userinfo failed: %v", err)
		http.Redirect(w, r, "/", 302)
		return
	}
	defer res.Body.Close()
	data, _ := ioutil.ReadAll(res.Body)

	ui := userinfo{}
	err = json.Unmarshal(data, &ui)
	if err != nil || ui.Email == "" {
		glog.Errorf("Userinfo unarshal failed: %v", err)
		http.Redirect(w, r, "/", 302)
		return
	}

	account, err := s.accountForEmail(ui.Email)
	if err != nil {
		glog.Errorf("account get failed: %v", err)
		http.Redirect(w, r, "/", 302)
		return
	}
	if account != "" {
		s.sessionPut(w, r, "account", account)
		http.Redirect(w, r, "/", 302)
	} else {
		s.sessionPut(w, r, "email", ui.Email)
		http.Redirect(w, r, "/setup", 302)
	}
}

func (s *server) viewOauthSetup(w http.ResponseWriter, r *http.Request) {
	email := s.sessionGet(r, "email")
	if email == "" {
		glog.Errorf("No email")
		http.Redirect(w, r, "/", 302)
		return
	}

	if r.Method == "GET" {
		tSetup.Execute(w, nil)
		return
	}

	username := r.FormValue("username")
	password := r.FormValue("password")
	if !reAccount.MatchString(username) {
		tSetup.Execute(w, map[string]string{
			"Username": username,
			"Error":    "Invalid username - must be 3-16 a-z 0-9 - _",
		})
		return
	}
	if !rePassword.MatchString(password) {
		tSetup.Execute(w, map[string]string{
			"Username": username,
			"Error":    "Invalid password - must be 3-16 a-z A-Z 0-9 - _",
		})
		return
	}

	// this races. ugh. no way to list users. yolo.
	err := createAccount(r.Context(), username, password)
	if err != nil {
		tSetup.Execute(w, map[string]string{
			"Username": username,
			"Error":    "Account already exists, pick a different username",
		})
		return
	}

	err = s.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte("emailToAccount"))
		v := string(b.Get([]byte(email)))
		if v != "" {
			s.sessionPut(w, r, "account", v)
			http.Redirect(w, r, "/", 302)
			return nil
		}
		b.Put([]byte(email), []byte(username))
		s.sessionPut(w, r, "account", username)
		http.Redirect(w, r, "/", 302)
		return nil
	})
	if err != nil {
		glog.Errorf("setup tx: %v", err)
		http.Redirect(w, r, "/", 302)
	}
}
func (s *server) viewReset(w http.ResponseWriter, r *http.Request) {
	account := s.sessionGet(r, "account")
	if account == "" {
		glog.Errorf("No account")
		http.Redirect(w, r, "/", 302)
		return
	}

	password := r.FormValue("password")
	if !rePassword.MatchString(password) {
		fmt.Fprintf(w, "pick a 3-16 password with not too many special chars")
		return
	}

	// this races. ugh. no way to list users. yolo.
	err := ensureAccount(r.Context(), account, password)
	if err != nil {
		glog.Errorf("ensureAccount(%q, _): %v", account, err)
		fmt.Fprintf(w, "something went wrong, lol")
		return
	}
	fmt.Fprintf(w, "new password set.")
}

func (s *server) viewLogout(w http.ResponseWriter, r *http.Request) {
	s.sessionPut(w, r, "account", "")
	s.sessionPut(w, r, "email", "")
	http.Redirect(w, r, "/", 302)
}

func (s *server) accountForEmail(email string) (string, error) {
	res := ""
	err := s.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte("emailToAccount"))
		v := b.Get([]byte(email))
		res = string(v)
		return nil
	})
	return res, err
}

type userinfo struct {
	Email string `json:"email"`
}
