// Package tool ...
//
// Description : util ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2023-12-27 17:06
package tool

import (
	"git.zhangdeman.cn/zhangdeman/wrapper"
	"git.zhangdeman.cn/zhangdeman/wrapper/tool/define"
)

var (
	Version = &version{}
)

type version struct {
}

// getVersionArr 解析版本号
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:42 2023/12/27
func (v *version) getVersionArr(versionOne string, versionTwo string) ([]int64, []int64, error) {
	oneWrapper := wrapper.String(versionOne).ToInt64Slice(".")
	twoWrapper := wrapper.String(versionTwo).ToInt64Slice(".")
	if oneWrapper.Err != nil {
		return nil, nil, oneWrapper.Err
	}
	if twoWrapper.Err != nil {
		return nil, nil, twoWrapper.Err
	}
	return oneWrapper.Value, twoWrapper.Value, nil
}

// Compare 比较版本号的大小, 版本号格式必须是 x.y.z 的形式,几个 . 不限制, x、y、z 必须是是数字
//
// strictMode 严格模式, 非严格模式下, 2.4 == 2.4.0 , 开启严格模式, 则认为 2.4 < 2.4.0 , 因为 2.4 没有小版本号
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:07 2023/12/27
func (v *version) Compare(versionOne string, versionTwo string, strictMode bool) (int, error) {
	oneVersionArr, twoVersionArr, err := v.getVersionArr(versionOne, versionTwo)
	if nil != err {
		return define.VersionCompareFail, err
	}
	oneVersionLength := len(oneVersionArr)
	twoVersionLength := len(twoVersionArr)
	// 版本号长度不一致补位
	if oneVersionLength > twoVersionLength {
		for fill := 0; fill < oneVersionLength-twoVersionLength; fill++ {
			twoVersionArr = append(twoVersionArr, 0)
		}
	}
	if oneVersionLength < twoVersionLength {
		for fill := 0; fill < twoVersionLength-oneVersionLength; fill++ {
			oneVersionArr = append(oneVersionArr, 0)
		}
	}

	// 开始比较
	for offset := 0; offset < len(oneVersionArr); offset++ {
		if oneVersionArr[offset] == twoVersionArr[offset] {
			// 当前位版本相等
			continue
		}
		if oneVersionArr[offset] > twoVersionArr[offset] {
			// 第一个版本号大
			return define.VersionOneMax, nil
		} else {
			// 第二个版本号大
			return define.VersionTwoMax, nil
		}
	}
	// 版本号一致, 判断严格模式与非严格模式
	if !strictMode || oneVersionLength == twoVersionLength {
		return define.VersionEqual, nil
	}
	return wrapper.TernaryOperator.Int(
		oneVersionLength > twoVersionLength,
		wrapper.Int(define.VersionOneMax),
		wrapper.Int(define.VersionTwoMax),
	).ToInt().Value, nil
}

// CompareIgnoreError 忽略error
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 18:20 2023/12/27
func (v *version) CompareIgnoreError(versionOne string, versionTwo string, strictMode bool) int {
	res, _ := v.Compare(versionOne, versionTwo, strictMode)
	return res
}