package main

// recurrent is a tool to bill recurrent monthly invoices. It should be run at
// the beginning of each month against a database of customers stored as a
// prototext.
//
// This is a fairly janky tool, and should be replaced by a proper billing
// service.
//
//    $ bazel run //bgpwtf/invoice/recurrent -- \
//        -invoice_configuration=$(pwd)bgpwtf/invoice/customers.pb.text \
//        -invoice_service 10.78.253.10:4200 -hspki_disable
//
// q3k has the sqlite database for the invoice service and the customer
// prototext.

import (
	"bufio"
	"context"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"time"

	"github.com/golang/glog"
	"github.com/golang/protobuf/proto"
	"google.golang.org/grpc"

	"code.hackerspace.pl/hscloud/go/pki"

	pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto"
)

func init() {
	flag.Set("logtostderr", "true")
}

var (
	flagConfiguration string
	flagService       string
)

func main() {
	flag.StringVar(&flagService, "invoice_service", "127.0.0.1:4200", "Address of invoice service")
	flag.StringVar(&flagConfiguration, "invoice_configuration", "customers.pb.text", "Prototext of customer data")
	flag.Parse()

	if flagConfiguration == "" {
		glog.Exit("-invoice_configuration must be set")
	}
	cfgBytes, err := ioutil.ReadFile(flagConfiguration)
	if err != nil {
		glog.Exitf("could not read configuration: %v", err)
	}

	var cfg pb.Configuration
	if err := proto.UnmarshalText(string(cfgBytes), &cfg); err != nil {
		glog.Exitf("UnmarshalText: %v", err)
	}

	conn, err := grpc.Dial(flagService, pki.WithClientHSPKI())
	if err != nil {
		glog.Exitf("Dial(%q): %v", flagService, err)
		return
	}
	svc := pb.NewInvoicerClient(conn)
	ctx := context.Background()

	var created []string
	now := time.Now()
	for _, sub := range cfg.Subscription {
		glog.Infof("Emitting for %q...", sub.Template.CustomerBilling[0])

		data := sub.Template
		if data.Date == 0 {
			data.Date = now.UnixNano()
		}

		date := time.Unix(0, data.Date)
		year := int(date.Year())
		month := int(date.Month())
		switch sub.Cycle {
		case pb.Subscription_CYCLE_CURRENT:
		case pb.Subscription_CYCLE_PREV:
			month -= 1
			if month < 1 {
				month = 12
				year -= 1
			}
		default:
			glog.Exitf("Invalid cycle: %v", sub.Cycle)
		}

		for _, item := range data.Item {
			item.Title = strings.ReplaceAll(item.Title, "%M", fmt.Sprintf("%02d", month))
			item.Title = strings.ReplaceAll(item.Title, "%Y", fmt.Sprintf("%04d", year))
		}
		res, err := svc.CreateInvoice(ctx, &pb.CreateInvoiceRequest{
			InvoiceData: data,
		})
		if err != nil {
			glog.Exitf("CreateInvoice: %v", err)
		}
		glog.Infof("Created invoice %q", res.Uid)
		created = append(created, res.Uid)
	}

	reader := bufio.NewReader(os.Stdin)
	fmt.Print("Invoices generated. Seal? [Yn]")
	text, err := reader.ReadString('\n')
	if err != nil {
		glog.Exitf("Response: %v", err)
	}
	switch strings.TrimSpace(strings.ToLower(text)) {
	case "", "y":
	default:
		glog.Exitf("Aborting.")
	}
	for _, uid := range created {
		glog.Infof("Sealing %q...", uid)
		_, err := svc.SealInvoice(ctx, &pb.SealInvoiceRequest{
			Uid:        uid,
			DateSource: pb.SealInvoiceRequest_DATE_SOURCE_PROFORMA,
			Language:   "pl",
		})
		if err != nil {
			glog.Errorf("Sealing %q failed: %v", uid, err)
			continue
		}
		res, err := svc.GetInvoice(ctx, &pb.GetInvoiceRequest{
			Uid: uid,
		})
		if err != nil {
			glog.Errorf("Retrieving sealed invoice %q failed: %v", uid, err)
			continue
		}
		fuid := res.Invoice.FinalUid
		glog.Infof("%q: Final UID: %s", uid, fuid)
		stream, err := svc.RenderInvoice(ctx, &pb.RenderInvoiceRequest{
			Uid: uid,
		})
		if err != nil {
			glog.Errorf("Rendering sealed invoice failed: %v", err)
			continue
		}

		path := fmt.Sprintf("/tmp/%s.pdf", strings.ReplaceAll(fuid, "/", ""))
		glog.Infof("Downloading %s...", path)
		f, err := os.Create(path)
		if err != nil {
			glog.Errorf("Create: %v", err)
			continue
		}

		for {
			block, err := stream.Recv()
			if err == io.EOF {
				break
			}
			if err != nil {
				glog.Errorf("Recv: %v", err)
				break
			}
			if _, err := f.Write(block.Data); err != nil {
				glog.Errorf("Write: %v", err)
				break
			}
		}
		f.Close()
	}

}
