package server

import (
	"log"
	"net/http"

	"git.autistici.org/ai3/go-common/serverutil"

	"git.autistici.org/id/keystore"
)

var emptyResponse struct{}

type keyStoreServer struct {
	*keystore.KeyStore
}

func (s *keyStoreServer) handleOpen(w http.ResponseWriter, r *http.Request) {
	var req keystore.OpenRequest
	if !serverutil.DecodeJSONRequest(w, r, &req) {
		return
	}

	err := s.KeyStore.Open(r.Context(), req.Username, req.Password, req.TTL)
	if err != nil {
		log.Printf("Open(%s) error: %v", req.Username, err)
		http.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	serverutil.EncodeJSONResponse(w, &emptyResponse)
}

func (s *keyStoreServer) handleGet(w http.ResponseWriter, r *http.Request) {
	var req keystore.GetRequest
	if !serverutil.DecodeJSONRequest(w, r, &req) {
		return
	}

	key, err := s.KeyStore.Get(req.Username, req.SSOTicket)
	if err != nil {
		log.Printf("Get(%s) error: %v", req.Username, err)
		http.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	serverutil.EncodeJSONResponse(w, &keystore.GetResponse{Key: key})
}

func (s *keyStoreServer) handleClose(w http.ResponseWriter, r *http.Request) {
	var req keystore.CloseRequest
	if !serverutil.DecodeJSONRequest(w, r, &req) {
		return
	}

	s.KeyStore.Close(req.Username)

	serverutil.EncodeJSONResponse(w, &emptyResponse)
}

func (s *keyStoreServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	switch r.URL.Path {
	case "/api/open":
		s.handleOpen(w, r)
	case "/api/get_key":
		s.handleGet(w, r)
	case "/api/close":
		s.handleClose(w, r)
	default:
		http.NotFound(w, r)
	}
}

func New(ks *keystore.KeyStore) http.Handler {
	return &keyStoreServer{ks}
}