package database

import (
	"io"
	"time"

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

// Tokens is the set of API calls needed to manage Token resources.
//
// Database backends should implement this interface.
type Tokens interface {
	io.Closer

	Get(ctx context.Context, id string) (Token, error)
	GetBody(ctx context.Context, body string) (Token, error)
	GetAll(ctx context.Context, user string) ([]Token, error)
	Put(ctx context.Context, t Token) (Token, error)
	Delete(ctx context.Context, id string) (Token, error)
	DeleteExpired(ctx context.Context) error
}

// Token is a single authorization token.
type Token struct {
	ID     string `storm:"id"`
	Body   string `storm:"unique"`
	Owner  string `storm:"index"`
	Scopes []string

	CreatedAt time.Time `json:"created_at"`
	ExpiresAt time.Time `json:"expires_at"`
	Active    bool      `json:"active"`
}

// F https://godoc.org/github.com/Xe/ln#F
func (t Token) F() ln.F {
	f := ln.F{
		"token-id":         t.ID,
		"token-owner":      t.Owner,
		"token-active":     t.Active,
		"token-created-at": t.CreatedAt.String(),
	}

	if !t.ExpiresAt.IsZero() {
		f["token-expires-at"] = t.ExpiresAt.String()
	}

	return f
}

// AsProto converts this into a protobuf Token.
func (t Token) AsProto() *proto.Token {
	return &proto.Token{
		Id:     t.ID,
		Body:   t.Body,
		Scopes: t.Scopes,
		Active: t.Active,
	}
}