package meta

import (
	"time"

	"k8s.io/apimachinery/pkg/fields"
	"k8s.io/apimachinery/pkg/labels"
)

// ObjectPhase is a int type, specific generation of an object state.
type ObjectPhase string

const (
	// ObjectPhasePreCreate is the phase that indicate object is pre-create.
	ObjectPhasePreCreate ObjectPhase = "PreCreate"

	// ObjectPhaseCreating is the phase that indicate object is creating.
	ObjectPhaseCreating ObjectPhase = "Creating"

	// ObjectPhaseCreated is the phase that indicate object is created
	ObjectPhaseCreated ObjectPhase = "Created"

	// ObjectPhasePreUpdate is the phase that indicate object is pre-update.
	ObjectPhasePreUpdate ObjectPhase = "PreUpdate"

	// ObjectPhaseUpdating is the phase that indicate object is updating.
	ObjectPhaseUpdating ObjectPhase = "Updating"

	// ObjectPhaseUpdated is the phase that indicate object is updated
	ObjectPhaseUpdated ObjectPhase = "Updated"

	// ObjectPhasePreDelete is the phase that indicate object is pre-delete.
	ObjectPhasePreDelete ObjectPhase = "PreDelete"

	// ObjectPhaseDeleting is the phase that indicate object is deleting.
	ObjectPhaseDeleting ObjectPhase = "Deleting"

	// ObjectPhaseDeleted is the phase that indicate object is deleted
	ObjectPhaseDeleted ObjectPhase = "Deleted"

	// ObjectPhasePreStart is the phase that indicate object is pre-start
	ObjectPhasePreStart ObjectPhase = "PreStart"

	// ObjectPhaseStarting is the phase that indicate object is starting
	ObjectPhaseStarting ObjectPhase = "Starting"

	// ObjectPhaseStarted is the phase that indicate object is started
	ObjectPhaseStarted ObjectPhase = "Started"

	// ObjectPhasePreStop is the phase that indicate object is pre-stop
	ObjectPhasePreStop ObjectPhase = "PreStop"

	// ObjectPhaseStopping is the phase that indicate object is stopping
	ObjectPhaseStopping ObjectPhase = "Stopping"

	// ObjectPhaseStopped is the phase that indicate object is stopped
	ObjectPhaseStopped ObjectPhase = "Stopped"

	// ObjectPhasePreRestart is the phase that indicate object is pre-restart
	ObjectPhasePreRestart ObjectPhase = "PreRestart"

	// ObjectPhaseRestarting is the phase that indicate object is restarting
	ObjectPhaseRestarting ObjectPhase = "Restarting"

	// ObjectPhaseRestarted is the phase that indicate object is restarted
	ObjectPhaseRestarted ObjectPhase = "Restarted"

	// ObjectPhasePreScale is the phase that indicate object is pre-scale
	ObjectPhasePreScale ObjectPhase = "PreScale"

	// ObjectPhaseScaling is the phase that indicate object is scaling
	ObjectPhaseScaling ObjectPhase = "Scaling"

	// ObjectPhaseScaled id the phase that indicate object is scaled
	ObjectPhaseScaled ObjectPhase = "Scaled"

	// ObjectPhasePreIncr is the phase than indicate object is pre-increment
	ObjectPhasePreIncr ObjectPhase = "PreIncr"

	// ObjectPhaseIncring is the phase that indicate object is incrementing
	ObjectPhaseIncring ObjectPhase = "Incring"

	// ObjectPhaseIncred is the phase that indicate object is incremented
	ObjectPhaseIncred ObjectPhase = "Incred"

	// ResourcePhaseScheduling is the phase that indicate resource is scheduling.
	ResourcePhaseScheduling ObjectPhase = "Scheduling"

	// ResourcePhaseScheduled is the phase that indicate resource is scheduled.
	ResourcePhaseScheduled ObjectPhase = "Scheduled"

	// ObjectPhaseFinish is the phase that indicate object's action is finish.
	ObjectPhaseFinish ObjectPhase = "Finish"
)

// ObjectMeta is metadata that all object must have.
type ObjectMeta struct {
	// Name is unique within a namespace.
	// Name is required when creating a object.
	// Name is primarily intended for creation idempotence and configuration definition.
	Name string `json:"Name,omitempty"`

	// Claimer is user name string to indicate who create this object.
	Claimer string `json:"Claimer,omitempty"`

	// Namespace defines the space within which name must be unique.
	// An empty namespace is equivalent to the "default" namespace.
	// TODO: Implement admission for each user in each namespace.
	Namespace string `json:"Namespace,omitempty"`

	// UID is unique string of this object, generate automatically.
	// UID is typically generated by the server on successful creation of a resource.
	// UID is not allowed to change on update operations.
	UID string `json:"UID,omitempty"`

	// Generation is a string representing a specific generation of the desired state.
	// Generation is populated by Syreo system, it is Read-Only for client side.
	Generation ObjectPhase `json:"Generation,omitempty"`

	// Labels are key value pairs that may be used to scope and select individual resources.
	Labels labels.Set `json:"Labels,omitempty"`

	// Annotations are unstructured key value data stored with a resource that may be set by
	// external tooling. They are not queryable and should be preserved when modifying
	// objects.  Annotation keys have the same formatting restrictions as Label keys. See the
	// comments on Labels for details.
	Annotations fields.Set `json:"Annotations,omitempty"`

	// CreationTimestamp is a timestamp representing the server time when this object was
	// created. It is not guaranteed to be set in happens-before order across separate operations.
	// Clients may not set this value. It is represented in RFC3339 form and is in UTC.
	CreationTimestamp *time.Time `json:"CreationTimestamp,omitempty"`

	// An opaque value that represents the version of this resource. May be used for optimistic
	// concurrency, change detection, and the watch operation on a resource or set of resources.
	// Clients must treat these values as opaque and values may only be valid for a particular
	// resource or set of resources. Only servers will generate resource versions.
	ResourceVersion int64 `json:"ResourceVersion,omitempty"`

	// ModifyTimestamp is a timestamp representing the server time when this object was
	// modified. It is not guaranteed to be set in happens-before order across separate operations.
	// Clients may not set this value. It is represented in RFC3339 form and is in UTC.

	ModifyTimestamp *time.Time `json:"ModifyTimestamp,omitempty"`
}
