package tepserver

import (
	"crypto/tls"
	"net/http"
	"net/http/httputil"

	"github.com/jinzhu/gorm"
	"github.com/pingcap/tep/pkg/tepserver/session"
	"github.com/pingcap/tep/pkg/utils"
)

type Server struct {
	DB                  *gorm.DB
	SessionManager      *session.Manager
	TLSConfig           *tls.Config
	APIPrefix           string
	APIServerPrefix     string
	KubeAPIServerHost   string
	KubeAPIServerPort   int
	PDStorageClass      string
	BackupStorageClass  string
	RemoteStorageClass  string
	TiKVStorageClass    string
	MonitorStorageClass string
	BackupStorageSize   string
	Endpoint            string
	AccessKey           string
	SecretKey           string
	Region              string
	Provider            string
	ACL                 string
	reserveProxy        *httputil.ReverseProxy
}

type ServerConfig struct {
	APIPrefix                  string
	APIServerPrefix            string
	KubeAPIServerHost          string
	KubeAPIServerPort          int
	KubeAPIServerSkipSSLVerify bool
	CAFilePath                 string
	CertFilePath               string
	KeyFilePath                string
	DSN                        string
	PDStorageClass             string
	BackupStorageClass         string
	RemoteStorageClass         string
	TiKVStorageClass           string
	MonitorStorageClass        string
	BackupStorageSize          string
	Endpoint                   string
	AccessKey                  string
	SecretKey                  string
	Region                     string
	Provider                   string
	ACL                        string
}

func NewServer(config *ServerConfig) (*Server, error) {
	db, err := gorm.Open("mysql", config.DSN)
	if err != nil {
		return nil, err
	}
	db.SingularTable(true)

	tlsConfig, err := utils.GetTLSConfig(config.CAFilePath, config.CertFilePath, config.KeyFilePath, config.KubeAPIServerSkipSSLVerify)
	if err != nil {
		return nil, err
	}

	s := &Server{
		DB:                  db,
		TLSConfig:           tlsConfig,
		APIPrefix:           config.APIPrefix,
		APIServerPrefix:     config.APIServerPrefix,
		KubeAPIServerHost:   config.KubeAPIServerHost,
		KubeAPIServerPort:   config.KubeAPIServerPort,
		PDStorageClass:      config.PDStorageClass,
		TiKVStorageClass:    config.TiKVStorageClass,
		BackupStorageClass:  config.BackupStorageClass,
		RemoteStorageClass:  config.RemoteStorageClass,
		MonitorStorageClass: config.MonitorStorageClass,
		BackupStorageSize:   config.BackupStorageSize,
		Endpoint:            config.Endpoint,
		AccessKey:           config.AccessKey,
		SecretKey:           config.SecretKey,
		Region:              config.Region,
		Provider:            config.Provider,
		ACL:                 config.ACL,
	}

	proxy := &httputil.ReverseProxy{Director: s.director}
	if tlsConfig != nil {
		proxy.Transport = &http.Transport{TLSClientConfig: tlsConfig}
	} else {
		http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
	}
	s.reserveProxy = proxy
	return s, nil
}
