package event

import (
	"context"
	"time"

	"github.com/golang/protobuf/ptypes/timestamp"
	"google.golang.org/grpc"

	pb "code.justin.tv/dta/rockpaperscissors/proto"
)

// Client is a client for the EventService gRPC service.
type Client struct {
	conn   *grpc.ClientConn
	client pb.EventServiceClient
}

// NewClient is a constructor for the client. Please call Close() when done.
func NewClient(address string) (*Client, error) {
	conn, err := grpc.Dial(address, grpc.WithInsecure())
	if err != nil {
		return nil, err
	}

	return &Client{
		conn:   conn,
		client: pb.NewEventServiceClient(conn),
	}, nil
}

// Close closes the client connection.
func (c *Client) Close() error {
	return c.conn.Close()
}

// AddEvent adds the given Event protobuf in the datastore.
func (c *Client) AddEvent(event *pb.Event) error {
	_, err := c.client.AddEvent(
		context.Background(),
		&pb.AddEventRequest{Event: event},
	)
	if err != nil {
		return err
	}
	return nil
}

// GetEvent simply returns the the given Event protobufs from the datastore.
func (c *Client) GetEvent(UUID []byte) (*pb.Event, error) {
	response, err := c.client.GetEvent(
		context.Background(),
		&pb.GetEventRequest{
			Uuid: UUID,
		},
	)
	if err != nil {
		return nil, err
	}
	return response.Event, nil
}

// QueryEvents returns a list of Event protobufs with ID and name.
func (c *Client) QueryEvents(start, end time.Time, eventType string, filters map[string]string) ([]*pb.Event, error) {
	request := &pb.QueryEventsRequest{
		Timerange: &pb.TimeRange{
			Start: &timestamp.Timestamp{
				Seconds: start.Unix(),
			},
			End: &timestamp.Timestamp{
				Seconds: end.Unix(),
			},
		},
		Type: eventType,
	}
	for k, v := range filters {
		request.Filters = append(request.Filters, &pb.QueryEventsRequest_AttributeFilter{
			Key:   k,
			Value: v,
		})
	}
	response, err := c.client.QueryEvents(context.Background(), request)
	if err != nil {
		return nil, err
	}
	return response.Events, nil
}
