package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/golang/glog"
	"google.golang.org/protobuf/encoding/prototext"
	admission "k8s.io/api/admission/v1beta1"
	meta "k8s.io/apimachinery/pkg/apis/meta/v1"

	pb "code.hackerspace.pl/hscloud/cluster/admitomatic/config"
)

type service struct {
	ingress ingressFilter
}

// newService creates an admitomatic service from a given prototext config.
func newService(configuration []byte) (*service, error) {
	var cfg pb.Config
	if err := prototext.Unmarshal(configuration, &cfg); err != nil {
		return nil, fmt.Errorf("parsing config: %v", err)
	}

	s := service{}

	for i, ad := range cfg.AllowDomain {
		if ad.Namespace == "" {
			ad.Namespace = "default"
		}
		if ad.Dns == "" {
			return nil, fmt.Errorf("config entry %d: dns must be set", i)
		}
		if err := s.ingress.allow(ad.Namespace, ad.Dns); err != nil {
			return nil, fmt.Errorf("config entry %d: %v", i, err)
		}
		glog.Infof("Ingress: allowing %s in %s", ad.Dns, ad.Namespace)
	}
	s.ingress.anythingGoesNamespaces = cfg.AnythingGoesNamespace
	return &s, nil
}

// handler is the main HTTP handler of the admitomatic service. It servers the
// AdmissionReview API, and is called by the Kubernetes API server to
// permit/deny creation/updating of resources.
func (s *service) handler(w http.ResponseWriter, r *http.Request) {
	var body []byte
	if r.Body != nil {
		if data, err := ioutil.ReadAll(r.Body); err == nil {
			body = data
		}
	}

	if r.Method != "POST" {
		glog.Errorf("%s %s: invalid method", r.Method, r.URL)
		return
	}

	contentType := r.Header.Get("Content-Type")
	if contentType != "application/json" {
		glog.Errorf("%s %s: invalid content-type", r.Method, r.URL)
		return
	}

	var review admission.AdmissionReview
	if err := json.Unmarshal(body, &review); err != nil {
		glog.Errorf("%s %s: cannot decode: %v", r.Method, r.URL, err)
		return
	}

	if review.Kind != "AdmissionReview" {
		glog.Errorf("%s %s: invalid Kind (%q)", r.Method, r.URL, review.Kind)
		return
	}

	var err error
	req := review.Request
	resp := &admission.AdmissionResponse{
		UID:     req.UID,
		Allowed: true,
	}
	switch {
	case req.Kind.Group == "networking.k8s.io" && req.Kind.Kind == "Ingress":
		resp, err = s.ingress.admit(req)
		if err != nil {
			glog.Errorf("%s %s %s: %v", req.Operation, req.Name, req.Namespace, err)
			// Fail safe.
			// TODO(q3k): monitor this?
			resp = &admission.AdmissionResponse{
				UID:     req.UID,
				Allowed: false,
				Result: &meta.Status{
					Code:    500,
					Message: "admitomatic: internal server error",
				},
			}
		}
	}

	glog.Infof("%s %s %s in %s: %v (%v)", req.Operation, req.Kind.Kind, req.Name, req.Namespace, resp.Allowed, resp.Result)
	review.Response = resp
	json.NewEncoder(w).Encode(review)
}
