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

	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 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)
		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()
}
