package alipay

import (
	"fmt"
	"os"
	"plugins/utils/helper"
	"sync"
)

type CertConfig struct {
	MchCertSN  string
	RootCertSN string
	PublicKey  string
}

type manager struct {
	once        sync.Once
	mutex       sync.RWMutex
	CertConfigs map[string]*CertConfig
}

var instance manager

func getCertConfig(appId string) *CertConfig {
	c, ok := instance.CertConfigs[appId]
	if !ok {
		return nil
	}
	return c
}

func setCertConfig(appId string, certConfig *CertConfig) {
	instance.mutex.Lock()
	defer instance.mutex.Unlock()
	instance.CertConfigs[appId] = certConfig
}

func init() {
	instance.CertConfigs = make(map[string]*CertConfig)
}

func GetCert(appId string) (*CertConfig, error) {
	c := getCertConfig(appId)
	if c != nil {
		return c, nil
	}
	dir, err := os.Getwd()
	if err != nil {
		return nil, fmt.Errorf("get current dir error: %v", err)
	}
	filePath := fmt.Sprintf("%s/%s/%s/%s", dir, "cert", "alipay", appId)
	if !helper.FileExists(filePath) {
		return nil, fmt.Errorf("appId[%s]支付宝密钥文件信息不存在,请联系技术人员处理", appId)
	}
	mchCertPath := fmt.Sprintf("%s/%s_%s.crt", filePath, "appCertPublicKey", appId)
	mchCertSN, err := getMchCertSN(mchCertPath)
	if err != nil {
		return nil, fmt.Errorf("get mchCertSN error: %v", err)
	}
	rootCertPath := fmt.Sprintf("%s/%s", filePath, "alipayRootCert.crt")
	rootCertSN, err := getRootCertSN(rootCertPath)
	if err != nil {
		return nil, fmt.Errorf("get rootCertSN error: %v", err)
	}
	publicKeyPath := fmt.Sprintf("%s/%s", filePath, "alipayCertPublicKey_RSA2.crt")
	publicKey, err := getPublicKey(publicKeyPath)
	if err != nil {
		return nil, fmt.Errorf("get publicKey error: %v", err)
	}
	c = &CertConfig{
		MchCertSN:  mchCertSN,
		RootCertSN: rootCertSN,
		PublicKey:  publicKey,
	}
	setCertConfig(appId, c)
	return c, nil
}