package server

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"local/oauth2/oauth2server/config"
	"net/http"

	"github.com/google/uuid"
)

func (s *Server) usersLog(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, `
      <html>
         <body>
            <form method="post" action="/authorize">
               <input type="text" name="username"></input>
               <input type="submit"></input>
            </form>
         </body>
      </html>
   `)
}

func (s *Server) usersRegister(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, `
      <html>
         <body>
            <form method="post" action="/users/submit">
               <input type="text" name="username"></input>
               <input type="submit"></input>
            </form>
         </body>
      </html>
   `)
}

func (s *Server) usersSubmit(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.NotFound(w, r)
		return
	}
	id := r.FormValue("username")
	if _, ok := s.getUser(id); ok {
		http.Error(w, "user already exists", http.StatusConflict)
		return
	}
	s.genUser(id)
}

func (s *Server) genUser(id string) {
	user := uuid.New().String()
	salt := uuid.New().String()
	s.store.Set(id, []byte(salt), SALT)
	obscured := s.obscureID(id)
	s.store.Set(obscured, []byte(user), USERS)
}

func (s *Server) getUser(id string) (string, bool) {
	obscured := s.obscureID(id)
	user, err := s.store.Get(obscured, USERS)
	return string(user), err == nil
}

func (s *Server) obscureID(id string) string {
	salt, _ := s.store.Get(id, SALT)
	a := s.obscure(string(salt)+id, config.SecretA)
	b := s.obscure(string(salt)+id, config.SecretB)
	return a + b
}

func (s *Server) obscure(payload, secret string) string {
	hash := md5.New()
	hash.Write([]byte(secret))
	key := hash.Sum(nil)
	sig := hmac.New(sha256.New, key)
	sig.Write([]byte(payload))
	return hex.EncodeToString(sig.Sum(nil))
}
