package main

import (
	"context"
	"flag"

	"github.com/golang/glog"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto"
	"code.hackerspace.pl/hscloud/go/mirko"
)

var (
	flagDatabasePath string
	flagInit         bool
	flagDisablePKI   bool
)

type service struct {
	m *model
}

func (s *service) CreateInvoice(ctx context.Context, req *pb.CreateInvoiceRequest) (*pb.CreateInvoiceResponse, error) {
	if err := validateInvoiceData(req.InvoiceData); err != nil {
		return nil, status.Errorf(codes.InvalidArgument, "invoice data: %v", err)
	}

	uid, err := s.m.createInvoice(ctx, req.InvoiceData)
	if err != nil {
		if _, ok := status.FromError(err); ok {
			return nil, err
		}
		glog.Errorf("createInvoice(_, _): %v", err)
		return nil, status.Error(codes.Unavailable, "could not create invoice")
	}
	return &pb.CreateInvoiceResponse{
		Uid: uid,
	}, nil
}

func (s *service) GetInvoice(ctx context.Context, req *pb.GetInvoiceRequest) (*pb.GetInvoiceResponse, error) {
	invoice, err := s.m.getInvoice(ctx, req.Uid)
	if err != nil {
		if _, ok := status.FromError(err); ok {
			return nil, err
		}
		glog.Errorf("getInvoice(_, %q): %v", req.Uid, err)
		return nil, status.Error(codes.Unavailable, "internal server error")
	}
	res := &pb.GetInvoiceResponse{
		Invoice: invoice,
	}
	return res, nil
}

func newService(m *model) *service {
	return &service{
		m: m,
	}
}

func (s *service) invoicePDF(ctx context.Context, uid, language string) ([]byte, error) {
	sealed, err := s.m.getSealedUid(ctx, uid)
	if err != nil {
		return nil, err
	}

	var rendered []byte
	if sealed != "" {
		// Invoice is sealed, return stored PDF.
		rendered, err = s.m.getRendered(ctx, uid)
		if err != nil {
			return nil, err
		}
	} else {
		// Invoice is proforma, render.
		invoice, err := s.m.getInvoice(ctx, uid)
		if err != nil {
			return nil, err
		}

		rendered, err = renderInvoicePDF(invoice, language)
		if err != nil {
			return nil, err
		}
	}
	return rendered, nil
}

func (s *service) RenderInvoice(req *pb.RenderInvoiceRequest, srv pb.Invoicer_RenderInvoiceServer) error {
	rendered, err := s.invoicePDF(srv.Context(), req.Uid, req.Language)
	if err != nil {
		if _, ok := status.FromError(err); ok {
			return err
		}
		glog.Errorf("invoicePDF(_, %q): %v", req.Uid, err)
		return status.Error(codes.Unavailable, "internal server error")
	}

	chunkSize := 16 * 1024
	chunk := &pb.RenderInvoiceResponse{}
	for i := 0; i < len(rendered); i += chunkSize {
		if i+chunkSize > len(rendered) {
			chunk.Data = rendered[i:len(rendered)]
		} else {
			chunk.Data = rendered[i : i+chunkSize]
		}
		if err := srv.Send(chunk); err != nil {
			glog.Errorf("srv.Send: %v", err)
			return status.Error(codes.Unavailable, "stream broken")
		}
	}
	return nil
}

func (s *service) SealInvoice(ctx context.Context, req *pb.SealInvoiceRequest) (*pb.SealInvoiceResponse, error) {
	useProformaTime := false
	if req.DateSource == pb.SealInvoiceRequest_DATE_SOURCE_PROFORMA {
		useProformaTime = true
	}
	if err := s.m.sealInvoice(ctx, req.Uid, req.Language, useProformaTime); err != nil {
		if _, ok := status.FromError(err); ok {
			return nil, err
		}
		glog.Errorf("sealInvoice(_, %q): %v", req.Uid, err)
		return nil, status.Error(codes.Unavailable, "internal server error")
	}
	return &pb.SealInvoiceResponse{}, nil
}

func (s *service) GetInvoices(req *pb.GetInvoicesRequest, srv pb.Invoicer_GetInvoicesServer) error {
	return status.Error(codes.Unimplemented, "unimplemented")
}

func init() {
	flag.Set("logtostderr", "true")
}

func main() {
	flag.StringVar(&flagDatabasePath, "db_path", "./foo.db", "path to sqlite database")
	flag.BoolVar(&flagInit, "init_db", false, "init database and exit")
	flag.Parse()

	m, err := newModel(flagDatabasePath)
	if err != nil {
		glog.Exitf("newModel: %v", err)
	}
	if flagInit {
		glog.Exit(m.init())
	}

	mi := mirko.New()
	if err := mi.Listen(); err != nil {
		glog.Exitf("Listen failed: %v", err)
	}

	s := newService(m)
	s.setupStatusz(mi)
	pb.RegisterInvoicerServer(mi.GRPC(), s)

	if err := mi.Serve(); err != nil {
		glog.Exitf("Serve failed: %v", err)
	}

	<-mi.Done()
}
