package types

import (
	"fmt"
	"time"

	"gitlink.org.cn/cloudream/common/pkgs/types"
	"gitlink.org.cn/cloudream/common/utils/serder"
)

type StorageID int64

type HubID int64

type LocationID int64

type UserID int64

type Hub struct {
	HubID          HubID          `gorm:"column:HubID; primaryKey; type:bigint; autoIncrement" json:"hubID"`
	Name           string         `gorm:"column:Name; type:varchar(255); not null" json:"name"`
	Address        HubAddressInfo `gorm:"column:Address; type:json; serializer:union" json:"address"`
	LocationID     LocationID     `gorm:"column:LocationID; type:bigint; not null" json:"locationID"`
	State          string         `gorm:"column:State; type:varchar(255); not null" json:"state"`
	LastReportTime *time.Time     `gorm:"column:LastReportTime; type:datetime" json:"lastReportTime"`
}

func (Hub) TableName() string {
	return "Hub"
}

type HubAddressInfo interface {
}

var HubAddressUnion = types.NewTypeUnion[HubAddressInfo](
	(*GRPCAddressInfo)(nil),
	(*HttpAddressInfo)(nil),
)

var _ = serder.UseTypeUnionInternallyTagged(&HubAddressUnion, "type")

type GRPCAddressInfo struct {
	serder.Metadata  `union:"GRPC"`
	Type             string `json:"type"`
	LocalIP          string `json:"localIP"`
	ExternalIP       string `json:"externalIP"`
	LocalGRPCPort    int    `json:"localGRPCPort"`
	ExternalGRPCPort int    `json:"externalGRPCPort"`
}

type HttpAddressInfo struct {
	serder.Metadata `union:"HTTP"`
	Type            string `json:"type"`
	LocalIP         string `json:"localIP"`
	ExternalIP      string `json:"externalIP"`
	Port            int    `json:"port"`
}

func (n Hub) String() string {
	return fmt.Sprintf("%v(%v)", n.Name, n.HubID)
}

type HubConnectivity struct {
	FromHubID HubID     `gorm:"column:FromHubID; primaryKey; type:bigint" json:"fromHubID"`
	ToHubID   HubID     `gorm:"column:ToHubID; primaryKey; type:bigint" json:"ToHubID"`
	Latency   *float32  `gorm:"column:Latency; type:float" json:"latency"`
	TestTime  time.Time `gorm:"column:TestTime; type:datetime" json:"testTime"`
}

func (HubConnectivity) TableName() string {
	return "HubConnectivity"
}

type Location struct {
	LocationID LocationID `gorm:"column:LocationID; primaryKey; type:bigint; autoIncrement" json:"locationID"`
	Name       string     `gorm:"column:Name; type:varchar(255); not null" json:"name"`
}

func (Location) TableName() string {
	return "Location"
}

type User struct {
	UserID UserID `gorm:"column:UserID; primaryKey; type:bigint; autoIncrement" json:"userID"`
	Name   string `gorm:"column:Name; type:varchar(255); not null" json:"name"`
}

func (User) TableName() string {
	return "User"
}
