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