package managecenterModel

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"

	"goutil/stringUtil"
	"goutil/typeUtil"
)

// 游戏版本
type ResourceVersion struct {
	// 资源版本唯一标识
	Id int32 `json:"ResourceVersionID"`

	// 资源版本名称
	Name string `json:"ResourceVersionName"`

	// 资源版本的url地址
	Url string `json:"ResourceVersionUrl"`

	// 资源大小
	Size int32 `json:"Size"`

	// 资源文件MD5加密的结果
	MD5 string `json:"MD5"`

	//大区Id
	AreaID int32 `json:"AreaID"`

	// 资源生效时间
	StartTime     string `json:"StartTime"`
	StartTimeTick int64  `json:"StartTimeTick"`

	// 资源失效时间
	EndTime     string `json:"EndTime"`
	EndTimeTick int64  `json:"EndTimeTick"`

	// 添加时间
	Crdate     string `json:"Crdate"`
	CrdateTick int64  `json:"CrdateTick"`

	// 更新时间
	UpdateTime     string `json:"UpdateTime"`
	UpdateTimeTick int64  `json:"UpdateTimeTick"`

	// 是否重启客户端
	IfRestart int32 `json:"IfRestart"`

	// 是否禁用
	IfDelete int32 `json:"IfDelete"`

	// 是否审核服下载
	IfAuditServiceDownload int32 `json:"IfAuditServiceDownload"`

	// 资源所属的合作商ID集合
	PartnerIds string `json:"PartnerIDs"`

	// 资源所属的游戏版本ID集合
	GameVersionIds string `json:"GameVersionIDs"`
}

// 判断资源是否包含指定合作商
// partnerId：合作商Id
// 返回值
// 是否包含
func (this *ResourceVersion) ContainsPartner(partnerId int32) bool {
	partnerIdList, _ := stringUtil.SplitToInt32Slice(this.PartnerIds, ",")
	for _, item := range partnerIdList {
		if item == partnerId {
			return true
		}
	}

	return false
}

//  判断资源是否包含指定游戏版本
// gameVersionId：游戏版本Id
// 返回值
// 是否包含
func (this *ResourceVersion) ContainsGameVersion(gameVersionId int32) bool {
	gameVersionIdList, _ := stringUtil.SplitToInt32Slice(this.GameVersionIds, ",")
	for _, item := range gameVersionIdList {
		if item == gameVersionId {
			return true
		}
	}

	return false
}

// 获取有效资源包
func GetAvailableResource(resourceVersionList []*ResourceVersion, partnerId, gameVersionId int32, resourceVersionName string, offTest OfficialOrTest) (availableResourceVersion map[string]interface{}) {

	if len(resourceVersionList) == 0 {
		return
	}

	//判断资源是否有效
	_, hashCode, isVaild := IsResourceVersionNameValid(resourceVersionName)
	if !isVaild {
		return
	}

	//根据合作商Id和游戏版本Id和开始时间来过滤
	var targetResourceVersionList []*ResourceVersion
	for _, resourceVersion := range resourceVersionList {
		startime, err := typeUtil.DateTime(resourceVersion.StartTimeTick)
		if resourceVersion.ContainsPartner(partnerId) && resourceVersion.ContainsGameVersion(gameVersionId) && err == nil && startime.Before(time.Now()) {
			targetResourceVersionList = append(targetResourceVersionList, resourceVersion)
		}
	}

	if len(targetResourceVersionList) == 0 {
		return
	}

	//组装数据

	//按照资源Id进行降序排列
	sort.Slice(targetResourceVersionList, func(i, j int) bool {
		return targetResourceVersionList[i].SortByIdDesc(targetResourceVersionList[j])
	})

	//取出资源号最大的资源，如果与传入的资源名称相等，则表示没有新资源
	availableResourceVersion = make(map[string]interface{}, 0)
	newResource := targetResourceVersionList[0]
	availableResourceVersion["ResourceVersionName"] = newResource.Name
	availableResourceVersion["Url"] = strings.Replace(newResource.Url, ".zip", "", -1)

	if newResource.Name == resourceVersionName {

		//是否有新资源，如果为fasle，也需要返回project.manifest.temp.zip 用于子包验证
		availableResourceVersion["IsNewResource"] = false

		return
	}

	//判断资源号中的HashCode是否相等，如果相等，则表示没有新资源；如果传入的timeTick>最新的timeTick说明服务器没有被刷新，表示没有新资源
	_, newHashCode, newIsVaild := IsResourceVersionNameValid(newResource.Name)
	if !newIsVaild {
		return
	}

	if compareRes := strings.Compare(hashCode, newHashCode); compareRes == 0 {
		//是否有新资源，如果为fasle，也需要返回project.manifest.temp.zip 用于子包验证
		availableResourceVersion["IsNewResource"] = false

		return
	}

	if offTest == Con_Test && newResource.IfAuditServiceDownload == 0 {
		return nil
	}

	availableResourceVersion["IsNewResource"] = true

	return
}

// 按照Id进行升序排序
// target:另一个资源对象
// 是否是小于
func (this *ResourceVersion) SortByIdAsc(target *ResourceVersion) bool {
	return this.Id < target.Id
}

// 按照Id进行降序排序
// target:另一个资源对象
// 是否是大于
func (this *ResourceVersion) SortByIdDesc(target *ResourceVersion) bool {
	return this.Id > target.Id
}

//判断资源版本是否有效
func IsResourceVersionNameValid(resourceVersionName string) (timeTick int64, hashCode string, isValid bool) {
	if len(resourceVersionName) == 0 {
		isValid = false

		return
	}

	if index := strings.Index(resourceVersionName, "_"); index == -1 {
		resourceVersionName = fmt.Sprintf("0_%s", resourceVersionName)
	}

	resourceList := stringUtil.Split(resourceVersionName, []string{"_"})
	if len(resourceList) != 2 {
		isValid = false

		return
	}

	//解析timeTick
	timeTick, err := strconv.ParseInt(resourceList[0], 10, 64)
	if err != nil {
		isValid = false

		return
	}

	hashCode = resourceList[1]
	isValid = true

	return
}
