package main

import (
	"context"
	"flag"

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

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

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 req.Invoice == nil {
		return nil, status.Error(codes.InvalidArgument, "invoice must be given")
	}
	if len(req.Invoice.Item) < 1 {
		return nil, status.Error(codes.InvalidArgument, "invoice must contain at least one item")
	}
	for i, item := range req.Invoice.Item {
		if item.Title == "" {
			return nil, status.Errorf(codes.InvalidArgument, "invoice item %d must have title set", i)
		}
		if item.Count == 0 || item.Count > 1000000 {
			return nil, status.Errorf(codes.InvalidArgument, "invoice item %d must have correct count", i)
		}
		if item.UnitPrice == 0 {
			return nil, status.Errorf(codes.InvalidArgument, "invoice item %d must have correct unit price", i)
		}
		if item.Vat > 100000 {
			return nil, status.Errorf(codes.InvalidArgument, "invoice item %d must have correct vat set", i)
		}
	}
	if len(req.Invoice.CustomerBilling) < 1 {
		return nil, status.Error(codes.InvalidArgument, "invoice must contain at least one line of the customer's billing address")
	}
	if len(req.Invoice.InvoicerBilling) < 1 {
		return nil, status.Error(codes.InvalidArgument, "invoice must contain at least one line of the invoicer's billing address")
	}
	for i, c := range req.Invoice.InvoicerContact {
		if c.Medium == "" {
			return nil, status.Errorf(codes.InvalidArgument, "contact point %d must have medium set", i)
		}
		if c.Contact == "" {
			return nil, status.Errorf(codes.InvalidArgument, "contact point %d must have contact set", i)
		}
	}
	if req.Invoice.InvoicerVatId == "" {
		return nil, status.Error(codes.InvalidArgument, "invoice must contain invoicer's vat id")
	}

	uid, err := s.m.createInvoice(ctx, req.Invoice)
	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")
	}
	sealedUid, err := s.m.getSealedUid(ctx, req.Uid)
	if err != nil {
		if _, ok := status.FromError(err); ok {
			return nil, err
		}
		glog.Errorf("getSealedUid(_, %q): %v", req.Uid, err)
		return nil, status.Error(codes.Unavailable, "internal server error")
	}

	res := &pb.GetInvoiceResponse{
		Invoice: invoice,
	}
	if sealedUid == "" {
		res.State = pb.GetInvoiceResponse_STATE_PROFORMA
	} else {
		res.State = pb.GetInvoiceResponse_STATE_SEALED
		res.FinalUid = sealedUid
	}

	return res, nil
}

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

func (s *service) invoicePDF(ctx context.Context, uid 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, "xxxx", true)
		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)
	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) {
	if err := s.m.sealInvoice(ctx, req.Uid); 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 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()
}
