package config

import (
	"bytes"

	"github.com/BurntSushi/toml"
)

type TiflowClusterMasterConfig struct {
	FrameworkMeta MetaDbConfig `toml:"framework-meta"`
	BusinessMeta  MetaDbConfig `toml:"business-meta"`
	Storage       Storage      `toml:"storage"`
}

const (
	MetaDBFrameworkSchemaPrefix    = "framework_"
	MetaDBBusinessMetaSchemaPrefix = "business_"
)

type Storage struct {
	S3  *S3Storage `toml:"s3,omitempty"`
	GCS *GCSConfig `toml:"gcs,omitempty"`
}

type S3Storage struct {
	Bucket       string `toml:"bucket,omitempty"`
	Prefix       string `toml:"prefix,omitempty"`
	Endpoint     string `toml:"endpoint,omitempty"`
	Region       string `toml:"region,omitempty"`
	StorageClass string `toml:"storage-class,omitempty"`
	ACL          string `toml:"acl,omitempty"`
	Provider     string `toml:"provider,omitempty"`
	RoleARN      string `toml:"role-arn,omitempty"`
}

type GCSConfig struct {
	Bucket          string `toml:"bucket,omitempty"`
	Prefix          string `toml:"prefix,omitempty"`
	Endpoint        string `toml:"endpoint,omitempty"`
	StorageClass    string `toml:"storage-class,omitempty"`
	PredefinedACL   string `toml:"predefined-acl,omitempty"`
	CredentialsFile string `toml:"credentials-file,omitempty"`
}

type MetaDbConfig struct {
	Schema    string   `toml:"schema"`
	Endpoints []string `toml:"endpoints"`
	User      string   `toml:"user"`
	Password  string   `toml:"password"`
}

type TiflowClusterExecutorConfig struct {
	Labels map[string]string `toml:"labels"`
}

func ConvertTiflowMasterConfig(cfg *TiflowClusterMasterConfig) (map[string]interface{}, error) {
	buf := new(bytes.Buffer)
	if err := toml.NewEncoder(buf).Encode(cfg); err != nil {
		return nil, err
	}
	genericConfig := map[string]interface{}{}
	if err := toml.Unmarshal(buf.Bytes(), &genericConfig); err != nil {
		return nil, err
	}
	return genericConfig, nil
}

func ConvertTiflowExecutorConfig(cfg *TiflowClusterExecutorConfig) (map[string]interface{}, error) {
	buf := new(bytes.Buffer)
	if err := toml.NewEncoder(buf).Encode(cfg); err != nil {
		return nil, err
	}
	genericConfig := map[string]interface{}{}
	if err := toml.Unmarshal(buf.Bytes(), &genericConfig); err != nil {
		return nil, err
	}
	return genericConfig, nil
}
