package tablestoredb

import (
	"fmt"
	"time"

	"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
	"gitlab.alibaba-inc.com/pai_biz_arch/pairec/recconf"
	"gitlab.alibaba-inc.com/pai_biz_arch/pairec/utils"
)

type TableStore struct {
	EndPoint        string
	InstanceName    string
	accessKeyId     string
	accessKeySecret string
	RoleArn         string
	Client          *tablestore.TableStoreClient
	Expiration      time.Time
}

var tablestoreInstances = make(map[string]*TableStore)

func GetTableStore(name string) (*TableStore, error) {
	if _, ok := tablestoreInstances[name]; !ok {
		return nil, fmt.Errorf("TableStore not found, name:%s", name)
	}

	return tablestoreInstances[name], nil
}
func (m *TableStore) SetAccessKeyId(id string) {
	m.accessKeyId = id
}

func (m *TableStore) SetAccessKeySecret(secret string) {
	m.accessKeySecret = secret
}

func (m *TableStore) Init() error {
	akId := m.accessKeyId
	akSecret := m.accessKeySecret
	securityToken := ""

	if m.RoleArn != "" {
		response, err := utils.AssumedRoleUser(recconf.Config.Region, m.RoleArn, "OTSAdmin")
		if err != nil {
			return err
		}

		akId = response.Credentials.AccessKeyId
		akSecret = response.Credentials.AccessKeySecret
		securityToken = response.Credentials.SecurityToken
		m.Expiration, _ = time.Parse(time.RFC3339, response.Credentials.Expiration)
		go m.loop()
	}
	client := tablestore.NewClientWithConfig(m.EndPoint, m.InstanceName, akId, akSecret, securityToken, nil)
	m.Client = client
	return nil
}
func (t *TableStore) loop() {
	for {
		time.Sleep(60 * time.Second)
		if t.Expiration.Sub(time.Now()) < 5*time.Minute {
			response, err := utils.AssumedRoleUser(recconf.Config.Region, t.RoleArn, "OTSAdmin")
			if err != nil {
				continue
			}

			akId := response.Credentials.AccessKeyId
			akSecret := response.Credentials.AccessKeySecret
			securityToken := response.Credentials.SecurityToken
			t.Expiration, _ = time.Parse(time.RFC3339, response.Credentials.Expiration)
			client := tablestore.NewClientWithConfig(t.EndPoint, t.InstanceName, akId, akSecret, securityToken, nil)
			t.Client = client

		}
	}

}
func Load(config *recconf.RecommendConfig) {
	for name, conf := range config.TableStoreConfs {
		t := &TableStore{
			EndPoint:        conf.EndPoint,
			InstanceName:    conf.InstanceName,
			accessKeyId:     conf.AccessKeyId,
			accessKeySecret: conf.AccessKeySecret,
			RoleArn:         conf.RoleArn,
		}
		err := t.Init()
		if err != nil {
			panic(err)
		}
		tablestoreInstances[name] = t
	}
}
