package common

import (
	"database/sql"
	"errors"
	"fmt"
	"strings"
	"sync"
	"time"
)

var (
	// DbMap 存放数据库连接的map
	DbMap *SafeMap
)

// SafeMap 并发安全
type SafeMap struct {
	Db map[string]*sql.DB
	mu sync.RWMutex
}

// NewSafeMap 创建并发安全的map
func NewSafeMap() *SafeMap {

	if DbMap == nil {
		DbMap = &SafeMap{
			Db: make(map[string]*sql.DB, 0),
		}
	}

	return DbMap
}

// GetOrStore 获取value 如果没有则放入map中 再进行获取
func (s *SafeMap) GetOrStore(key string) (*sql.DB, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	db, ok := s.Db[key]
	if ok {
		// err := db.Ping()
		if err != nil {
			return nil, err
		}
		return db, nil
	}
	db, err = newDBConn(key)
	if err != nil {
		return nil, err
	}
	// db.SetConnMaxLifetime()
	s.Db[key] = db
	return db, nil
}

// Store 往map中放入数据
func (s *SafeMap) Store(key string) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	db, err := newDBConn(key)
	if err != nil {
		return err
	}
	s.Db[key] = db
	return nil
}

func newDBConn(s string) (*sql.DB, error) {

	chainCode := strings.ToLower(s)
	if chainCode == "" {
		return nil, err
	}
	// if len(chainCode[:1]) != 1 {
	// 	return nil, err
	// }
	// word := chainCode[:1]
	// i ~ z
	// if word > "h" {
	// 	db, err := sql.Open("mysql", fmt.Sprintf(`root_dbc:dbc_root888888@tcp(rm-2ze095l91j14r251wno.mysql.rds.aliyuncs.com:3306)/dbc_%s?charset=utf8`,
	// 		chainCode))
	// 	if err != nil {
	// 		return nil, err
	// 	}
	// 	db.SetConnMaxLifetime(10 * time.Minute)
	// 	err = db.Ping()
	// 	return db, err
	// }

	// db, err := sql.Open("mysql", fmt.Sprintf(`root_dbc:dbc_root888888@tcp(rm-2ze8jnj44l6ta299pro.mysql.rds.aliyuncs.com:3306)/dbc_%s?charset=utf8`,
	// 	chainCode))
	// if err != nil {
	// 	return nil, err
	// }
	// db.SetConnMaxLifetime(10 * time.Minute)
	// err = db.Ping()
	// return db, err

	if strings.ToLower(chainCode)[0] >= '0' && strings.ToLower(chainCode)[0] <= '8' {

		db, err := sql.Open("mysql", fmt.Sprintf(`root_dbc:dbc_root888888@tcp(rm-2zej0q2rx321k0h1pbo.mysql.rds.aliyuncs.com:3306)/dbc_%s?charset=utf8`,
			chainCode))
		if err != nil {
			return nil, err
		}
		db.SetConnMaxLifetime(10 * time.Minute)
		err = db.Ping()
		if err != nil {
			return nil, err
		}
		return db, err
	} else if strings.ToLower(chainCode)[0] >= '9' && strings.ToLower(chainCode)[0] <= 'h' {

		db, err := sql.Open("mysql", fmt.Sprintf(`root_dbc:dbc_root888888@tcp(rm-2ze4xxt6w2959o0ftyo.mysql.rds.aliyuncs.com:3306)/dbc_%s?charset=utf8`,
			chainCode))
		if err != nil {
			return nil, err
		}
		db.SetConnMaxLifetime(10 * time.Minute)
		err = db.Ping()
		if err != nil {
			return nil, err
		}
		return db, err
	} else if strings.ToLower(chainCode)[0] >= 'i' && strings.ToLower(chainCode)[0] <= 'q' {

		db, err := sql.Open("mysql", fmt.Sprintf(`root_dbc:dbc_root888888@tcp(rm-2ze095l91j14r251wno.mysql.rds.aliyuncs.com:3306)/dbc_%s?charset=utf8`,
			chainCode))
		if err != nil {
			return nil, err
		}
		db.SetConnMaxLifetime(10 * time.Minute)
		err = db.Ping()
		if err != nil {
			return nil, err
		}
		return db, err
	} else if strings.ToLower(chainCode)[0] >= 'r' && strings.ToLower(chainCode)[0] <= 'z' {

		db, err := sql.Open("mysql", fmt.Sprintf(`root_dbc:dbc_root888888@tcp(rm-2zeg6r1nvfk968lixyo.mysql.rds.aliyuncs.com:3306)/dbc_%s?charset=utf8`,
			chainCode))
		if err != nil {
			return nil, err
		}
		db.SetConnMaxLifetime(10 * time.Minute)
		err = db.Ping()
		if err != nil {
			return nil, err
		}
		return db, err
	} else {
		return nil, errors.New("find error chain code")
	}

}
