package server

import (
	"git.xeserv.us/xena/route/internal/tun2"
	proto "git.xeserv.us/xena/route/proto"
	"github.com/Xe/ln"
	"golang.org/x/net/context"
)

// Backend implements proto.BackendsServer for gRPC.
type Backend struct {
	*Server
}

// List returns a list of backends given filtering parameters.
func (b *Backend) List(ctx context.Context, sel *proto.BackendSelector) (*proto.BackendList, error) {
	clitok, err := b.getAuth(ctx, "backend list", "backend:list")
	if err != nil {
		return nil, handleError(ctx, clitok, err, ln.F{"action": "authentication for backend list"})
	}

	bl := map[string]tun2.Backend{}

	switch {
	case sel.Domain != "":
		for _, bk := range b.ts.GetBackendsForDomain(sel.Domain) {
			bl[bk.ID] = bk
		}
	case sel.User != "":
		for _, bk := range b.ts.GetBackendsForUser(sel.User) {
			bl[bk.ID] = bk
		}
	default:
		for _, bk := range b.ts.GetAllBackends() {
			bl[bk.ID] = bk
		}
	}

	resp := &proto.BackendList{
		Bs: sel,
	}

	for _, bk := range bl {
		resp.Backends = append(resp.Backends, &proto.Backend{
			Id:     bk.ID,
			Proto:  bk.Proto,
			User:   bk.User,
			Domain: bk.Domain,
			Phi:    bk.Phi,
			Host:   bk.Host,
			Usable: bk.Usable,
		})
	}

	return resp, nil
}

// Kill removes a backend's connection by ID.
func (b *Backend) Kill(ctx context.Context, bid *proto.BackendID) (*proto.Nil, error) {
	clitok, err := b.getAuth(ctx, "backend list", "backend:list")
	if err != nil {
		return nil, handleError(ctx, clitok, err, ln.F{"action": "authentication for backend list"})
	}

	if err := b.ts.KillBackend(bid.Id); err != nil {
		return nil, handleError(ctx, clitok, err, ln.F{"action": "killing backend", "backend_id": bid.Id})
	}

	ln.Log(ctx, clitok, ln.Action("backend killed"), ln.F{"backend_id": bid.Id})

	return &proto.Nil{}, nil
}
