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