package main

import (
	"fmt"

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

// validateGTUCodde returns a non-nil error if the given GTU (Grupy Towarów i
// Usług) code is invalid.
func validateGTUCode(c pb.GTUCode) error {
	switch c {
	case pb.GTUCode_GTU_01:
	case pb.GTUCode_GTU_02:
	case pb.GTUCode_GTU_03:
	case pb.GTUCode_GTU_04:
	case pb.GTUCode_GTU_05:
	case pb.GTUCode_GTU_06:
	case pb.GTUCode_GTU_07:
	case pb.GTUCode_GTU_09:
	case pb.GTUCode_GTU_10:
	case pb.GTUCode_GTU_11:
	case pb.GTUCode_GTU_12:
	case pb.GTUCode_GTU_13:
	default:
		return fmt.Errorf("must be 1-13, is %d", c)
	}
	return nil
}

// validateGTUCodde returns a non-nil error if the given SP (Symbol Procedury)
// code is invalid.
func validateSPCode(c pb.SPCode) error {
	switch c {
	case pb.SPCode_SP_SW:
	case pb.SPCode_SP_EE:
	case pb.SPCode_SP_TP:
	case pb.SPCode_SP_TT_WNT:
	case pb.SPCode_SP_TT_D:
	case pb.SPCode_SP_MR_T:
	case pb.SPCode_SP_MR_UZ:
	case pb.SPCode_SP_I_42:
	case pb.SPCode_SP_I_63:
	case pb.SPCode_SP_B_SPV:
	case pb.SPCode_SP_B_SPV_DOSTAWA:
	case pb.SPCode_SP_B_MPV_PROWIZJA:
	case pb.SPCode_SP_MPP:
	default:
		return fmt.Errorf("unsupported value")
	}
	return nil
}

// validateItem returns a non-nil error if the given Item is invalid as part of
// an InvoiceData when an invoice is being created.
func validateItem(i *pb.Item) error {
	if i.Title == "" {
		return fmt.Errorf("must have title set")
	}
	if i.Count == 0 || i.Count > 1000000 {
		return fmt.Errorf("must have correct count")
	}
	if i.UnitPrice == 0 {
		return fmt.Errorf("must have correct unit price")
	}
	if i.Vat > 100000 {
		return fmt.Errorf("must have correct vat set")
	}
	for i, code := range i.GtuCode {
		if err := validateGTUCode(code); err != nil {
			return fmt.Errorf("GTU code %d: %v", i, err)
		}
	}
	return nil
}

// validateContactPoint returns a non-nil error if the given ContactPoint is
// invalid as part of an InvoiceData when an invoice is being created.
func validateContactPoint(cp *pb.ContactPoint) error {
	if cp.Medium == "" {
		return fmt.Errorf("must have medium set")
	}
	if cp.Contact == "" {
		return fmt.Errorf("must have contact set")
	}
	return nil
}

// validateInvoiceData returns a non-nil error if the given InvoiceData cannot
// be used to createa new invoice.
func validateInvoiceData(id *pb.InvoiceData) error {
	if id == nil {
		return fmt.Errorf("must be given")
	}
	if len(id.Item) < 1 {
		return fmt.Errorf("must contain at least one item")
	}
	for i, item := range id.Item {
		if err := validateItem(item); err != nil {
			return fmt.Errorf("invoice data item %d: %v", i, err)
		}
	}
	if len(id.CustomerBilling) < 1 {
		return fmt.Errorf("must contain at least one line of the customer's billing address")
	}
	if len(id.InvoicerBilling) < 1 {
		return fmt.Errorf("must contain at least one line of the invoicer's billing address")
	}
	for i, c := range id.InvoicerContact {
		if err := validateContactPoint(c); err != nil {
			return fmt.Errorf("contact point %d: %v", i, err)
		}
	}
	if id.InvoicerVatId == "" {
		return fmt.Errorf("must contain invoicer's vat id")
	}
	for i, code := range id.SpCode {
		if err := validateSPCode(code); err != nil {
			return fmt.Errorf("SP code %d: %v", i, err)
		}
	}
	return nil
}
