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) RenderInvoice(req *pb.RenderInvoiceRequest, srv pb.Invoicer_RenderInvoiceServer) error {
	sealed, err := s.m.getSealedUid(srv.Context(), req.Uid)
	if err != nil {
		if _, ok := status.FromError(err); ok {
			return err
		}
		glog.Errorf("getSealedUid(_, %q): %v", req.Uid, err)
		return status.Error(codes.Unavailable, "internal server error")
	}

	var rendered []byte
	if sealed != "" {
		// Invoice is sealed, return stored PDF.
		rendered, err = s.m.getRendered(srv.Context(), req.Uid)
		if err != nil {
			if _, ok := status.FromError(err); ok {
				return err
			}
			glog.Errorf("getRendered(_, %q): %v", req.Uid, err)
			return status.Error(codes.Unavailable, "internal server error")
		}
	} else {
		// Invoice is proforma, render.
		invoice, err := s.m.getInvoice(srv.Context(), req.Uid)
		if err != nil {
			if _, ok := status.FromError(err); ok {
				return err
			}
			glog.Errorf("getInvoice(_, %q): %v", req.Uid, err)
			return status.Error(codes.Unavailable, "internal server error")
		}

		glog.Infof("%+v", invoice)
		rendered, err = renderInvoicePDF(invoice, "xxxx", true)
		if err != nil {
			glog.Errorf("renderProformaPDF(_): %v", 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)
	pb.RegisterInvoicerServer(mi.GRPC(), s)

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

	<-mi.Done()
}
