package models

import "sort"

// SortedArgValues returns arg Values: readonly args first (sorted by Index), then non-readonly in order.
func SortedArgValues(args []Arg) []string {
	var ro, nro []Arg
	for _, a := range args {
		if a.IsReadonly {
			ro = append(ro, a)
		} else {
			nro = append(nro, a)
		}
	}
	sort.Slice(ro, func(i, j int) bool { return ro[i].Index < ro[j].Index })
	out := make([]string, 0, len(args))
	for _, a := range ro {
		out = append(out, a.Value)
	}
	for _, a := range nro {
		out = append(out, a.Value)
	}
	return out
}

// ReadonlyArgValues returns only the readonly arg values sorted by Index.
func ReadonlyArgValues(args []Arg) []string {
	var ro []Arg
	for _, a := range args {
		if a.IsReadonly {
			ro = append(ro, a)
		}
	}
	sort.Slice(ro, func(i, j int) bool { return ro[i].Index < ro[j].Index })
	out := make([]string, 0, len(ro))
	for _, a := range ro {
		out = append(out, a.Value)
	}
	return out
}

// NonReadonlyArgValues returns only the non-readonly arg values in their order.
func NonReadonlyArgValues(args []Arg) []string {
	out := make([]string, 0)
	for _, a := range args {
		if !a.IsReadonly {
			out = append(out, a.Value)
		}
	}
	return out
}

type Arg struct {
	Value      string `json:"value,omitempty" bson:"value,omitempty"` // Image is the container image TEMPO
	Index      int    `json:"index,omitempty" bson:"index,omitempty"`
	IsReadonly bool   `json:"is_readonly,omitempty" bson:"is_readonly,omitempty"`
}

type PathSource struct {
	Source      string            `json:"source,omitempty" bson:"source,omitempty"` // Image is the container image TEMPO
	IsReachable bool              `json:"is_reachable,omitempty" bson:"is_reachable,omitempty"`
	Args        []Arg             `json:"args,omitempty" bson:"args,omitempty"`       // Args is the container arguments
	Volumes     map[string]string `json:"volumes,omitempty" bson:"volumes,omitempty"` // Volumes is the container volumes
}

type Container struct {
	PathSource

	Image   string `json:"image,omitempty" bson:"image,omitempty"`     // Image is the container image TEMPO
	Command string `json:"command,omitempty" bson:"command,omitempty"` // Command is the container command
}

type Expose struct {
	Port    int    `json:"port,omitempty" bson:"port,omitempty"`       // Port is the port
	Reverse string `json:"reverse,omitempty" bson:"reverse,omitempty"` // Reverse is the reverse
	PAT     int    `json:"pat,omitempty" bson:"pat,omitempty"`         // PAT is the PAT
}
