package payment

import (
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"strings"

	"github.com/go-pay/gopay"
)

// toGoPayBodyMap keeps provider protocol types inside the data layer while
// allowing GoPay's signing and notification helpers to be reused.
func toGoPayBodyMap(values map[string]string) gopay.BodyMap {
	bm := make(gopay.BodyMap, len(values))
	for key, value := range values {
		bm[key] = value
	}
	return bm
}

func cloneGoPayBodyMap(values gopay.BodyMap) gopay.BodyMap {
	clone := make(gopay.BodyMap, len(values))
	for key, value := range values {
		clone[key] = value
	}
	return clone
}

func fromGoPayBodyMap(values gopay.BodyMap) map[string]string {
	result := make(map[string]string, len(values))
	for key := range values {
		result[key] = values.GetString(key)
	}
	return result
}

// goPayAlipayKey converts the PEM-friendly configuration accepted by this
// service into GoPay's raw base64 key format. GoPay's Alipay helpers add their
// own PEM envelope internally.
func goPayAlipayKey(value string, public bool) string {
	value = strings.TrimSpace(value)
	if block, _ := pem.Decode([]byte(value)); block != nil {
		der := block.Bytes
		if public && block.Type == "CERTIFICATE" {
			if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
				if pub, err := x509.MarshalPKIXPublicKey(cert.PublicKey); err == nil {
					der = pub
				}
			}
		}
		return base64.StdEncoding.EncodeToString(der)
	}
	return strings.Join(strings.Fields(value), "")
}
