package shared

import (
	"io/fs"
	"os"
	"path"
	"strings"
)

type Operation string

const (
	Deploy   = Operation("deploy")
	Withdraw = Operation("withdraw")
	Upgrade  = Operation("upgrade")
	Start    = Operation("start")
	Restart  = Operation("restart")
	Stop     = Operation("stop")
	Upload   = Operation("upload")
)

type DeployRequest struct {
	Name        string
	Version     string
	Url         string
	Config      string
	AccessToken string
}

type WithdrawRequest struct {
	Name    string
	Version string
}

type StartProcessRequest struct {
	Name    string
	Version string
	Args    []string
}

type StopProcessRequest struct {
	Name    string
	Version string
	Pid     int32
}

type RestartProcessRequest struct {
	Name   string
	Pid    int32
	Config string
}

type UploadRequest struct {
	Name                string
	Version             string
	Url                 string
	Filter              string
	DeleteAfterUploaded string // true, false
}

type ParsedVersionString = []string

func ParseVersionString(ver string) ParsedVersionString {
	return strings.Split(ver, ".")
}

func CompareVersionString(lhs, rhs ParsedVersionString) int {
	minlen := len(lhs)
	if minlen > len(rhs) {
		minlen = len(rhs)
	}

	for i := 0; i < minlen; i++ {
		if len(lhs[i]) < len(rhs[i]) {
			return -1
		}

		if len(lhs[i]) > len(rhs[i]) {
			return 1
		}

		if lhs[i] < rhs[i] {
			return -1
		}

		if lhs[i] > rhs[i] {
			return 1
		}
	}

	return len(lhs) - len(rhs)
}

func FindLastestVersion(storageRoot, name string) (string, error) {
	// 최신 버전을 찾음
	targetPath := path.Join(storageRoot, name)
	entries, err := os.ReadDir(targetPath)
	if err != nil {
		return "", err
	}
	if len(entries) == 0 {
		return "", nil
	}
	var dironly []fs.DirEntry
	for _, ent := range entries {
		if ent.IsDir() {
			dironly = append(dironly, ent)
		}
	}
	latest := ParseVersionString(dironly[0].Name())
	for i := 1; i < len(dironly); i++ {
		next := ParseVersionString(dironly[i].Name())
		if CompareVersionString(latest, next) < 0 {
			latest = next
		}
	}
	return strings.Join(latest, "."), nil
}
