// Package relationship provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.1 DO NOT EDIT.
package relationship

import (
	"encoding/json"
	"fmt"

	core "github.com/meshery/schemas/models/core"
	capabilityv1beta1 "github.com/meshery/schemas/models/v1beta1/capability"
	modelv1beta1 "github.com/meshery/schemas/models/v1beta1/model"
)

// Defines values for RelationshipDefinitionKind.
const (
	Edge         RelationshipDefinitionKind = "edge"
	Hierarchical RelationshipDefinitionKind = "hierarchical"
	Sibling      RelationshipDefinitionKind = "sibling"
)

// Defines values for RelationshipDefinitionStatus.
const (
	Approved RelationshipDefinitionStatus = "approved"
	Deleted  RelationshipDefinitionStatus = "deleted"
	Enabled  RelationshipDefinitionStatus = "enabled"
	Ignored  RelationshipDefinitionStatus = "ignored"
	Pending  RelationshipDefinitionStatus = "pending"
)

// Defines values for RelationshipDefinitionMetadataStylesArrowShape.
const (
	RelationshipDefinitionMetadataStylesArrowShapeChevron           RelationshipDefinitionMetadataStylesArrowShape = "chevron"
	RelationshipDefinitionMetadataStylesArrowShapeCircle            RelationshipDefinitionMetadataStylesArrowShape = "circle"
	RelationshipDefinitionMetadataStylesArrowShapeCircleTriangle    RelationshipDefinitionMetadataStylesArrowShape = "circle-triangle"
	RelationshipDefinitionMetadataStylesArrowShapeDiamond           RelationshipDefinitionMetadataStylesArrowShape = "diamond"
	RelationshipDefinitionMetadataStylesArrowShapeNone              RelationshipDefinitionMetadataStylesArrowShape = "none"
	RelationshipDefinitionMetadataStylesArrowShapeSquare            RelationshipDefinitionMetadataStylesArrowShape = "square"
	RelationshipDefinitionMetadataStylesArrowShapeTee               RelationshipDefinitionMetadataStylesArrowShape = "tee"
	RelationshipDefinitionMetadataStylesArrowShapeTriangle          RelationshipDefinitionMetadataStylesArrowShape = "triangle"
	RelationshipDefinitionMetadataStylesArrowShapeTriangleBackcurve RelationshipDefinitionMetadataStylesArrowShape = "triangle-backcurve"
	RelationshipDefinitionMetadataStylesArrowShapeTriangleCross     RelationshipDefinitionMetadataStylesArrowShape = "triangle-cross"
	RelationshipDefinitionMetadataStylesArrowShapeTriangleTee       RelationshipDefinitionMetadataStylesArrowShape = "triangle-tee"
	RelationshipDefinitionMetadataStylesArrowShapeVee               RelationshipDefinitionMetadataStylesArrowShape = "vee"
)

// Defines values for RelationshipDefinitionMetadataStylesCurveStyle.
const (
	Bezier          RelationshipDefinitionMetadataStylesCurveStyle = "bezier"
	Haystack        RelationshipDefinitionMetadataStylesCurveStyle = "haystack"
	Segments        RelationshipDefinitionMetadataStylesCurveStyle = "segments"
	Straight        RelationshipDefinitionMetadataStylesCurveStyle = "straight"
	Taxi            RelationshipDefinitionMetadataStylesCurveStyle = "taxi"
	UnbundledBezier RelationshipDefinitionMetadataStylesCurveStyle = "unbundled-bezier"
)

// Defines values for RelationshipDefinitionMetadataStylesLineCap.
const (
	RelationshipDefinitionMetadataStylesLineCapButt   RelationshipDefinitionMetadataStylesLineCap = "butt"
	RelationshipDefinitionMetadataStylesLineCapRound  RelationshipDefinitionMetadataStylesLineCap = "round"
	RelationshipDefinitionMetadataStylesLineCapSquare RelationshipDefinitionMetadataStylesLineCap = "square"
)

// Defines values for RelationshipDefinitionMetadataStylesLineStyle.
const (
	Dashed RelationshipDefinitionMetadataStylesLineStyle = "dashed"
	Dotted RelationshipDefinitionMetadataStylesLineStyle = "dotted"
	Solid  RelationshipDefinitionMetadataStylesLineStyle = "solid"
)

// Defines values for RelationshipDefinitionMetadataStylesMidTargetArrowFill.
const (
	RelationshipDefinitionMetadataStylesMidTargetArrowFillFilled RelationshipDefinitionMetadataStylesMidTargetArrowFill = "filled"
	RelationshipDefinitionMetadataStylesMidTargetArrowFillHollow RelationshipDefinitionMetadataStylesMidTargetArrowFill = "hollow"
)

// Defines values for RelationshipDefinitionMetadataStylesMidTargetArrowShape.
const (
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeChevron           RelationshipDefinitionMetadataStylesMidTargetArrowShape = "chevron"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeCircle            RelationshipDefinitionMetadataStylesMidTargetArrowShape = "circle"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeCircleTriangle    RelationshipDefinitionMetadataStylesMidTargetArrowShape = "circle-triangle"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeDiamond           RelationshipDefinitionMetadataStylesMidTargetArrowShape = "diamond"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeNone              RelationshipDefinitionMetadataStylesMidTargetArrowShape = "none"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeSquare            RelationshipDefinitionMetadataStylesMidTargetArrowShape = "square"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeTee               RelationshipDefinitionMetadataStylesMidTargetArrowShape = "tee"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeTriangle          RelationshipDefinitionMetadataStylesMidTargetArrowShape = "triangle"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeTriangleBackcurve RelationshipDefinitionMetadataStylesMidTargetArrowShape = "triangle-backcurve"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeTriangleCross     RelationshipDefinitionMetadataStylesMidTargetArrowShape = "triangle-cross"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeTriangleTee       RelationshipDefinitionMetadataStylesMidTargetArrowShape = "triangle-tee"
	RelationshipDefinitionMetadataStylesMidTargetArrowShapeVee               RelationshipDefinitionMetadataStylesMidTargetArrowShape = "vee"
)

// Defines values for RelationshipDefinitionMetadataStylesTargetArrowFill.
const (
	RelationshipDefinitionMetadataStylesTargetArrowFillFilled RelationshipDefinitionMetadataStylesTargetArrowFill = "filled"
	RelationshipDefinitionMetadataStylesTargetArrowFillHollow RelationshipDefinitionMetadataStylesTargetArrowFill = "hollow"
)

// Defines values for RelationshipDefinitionMetadataStylesTargetArrowShape.
const (
	RelationshipDefinitionMetadataStylesTargetArrowShapeChevron           RelationshipDefinitionMetadataStylesTargetArrowShape = "chevron"
	RelationshipDefinitionMetadataStylesTargetArrowShapeCircle            RelationshipDefinitionMetadataStylesTargetArrowShape = "circle"
	RelationshipDefinitionMetadataStylesTargetArrowShapeCircleTriangle    RelationshipDefinitionMetadataStylesTargetArrowShape = "circle-triangle"
	RelationshipDefinitionMetadataStylesTargetArrowShapeDiamond           RelationshipDefinitionMetadataStylesTargetArrowShape = "diamond"
	RelationshipDefinitionMetadataStylesTargetArrowShapeNone              RelationshipDefinitionMetadataStylesTargetArrowShape = "none"
	RelationshipDefinitionMetadataStylesTargetArrowShapeSquare            RelationshipDefinitionMetadataStylesTargetArrowShape = "square"
	RelationshipDefinitionMetadataStylesTargetArrowShapeTee               RelationshipDefinitionMetadataStylesTargetArrowShape = "tee"
	RelationshipDefinitionMetadataStylesTargetArrowShapeTriangle          RelationshipDefinitionMetadataStylesTargetArrowShape = "triangle"
	RelationshipDefinitionMetadataStylesTargetArrowShapeTriangleBackcurve RelationshipDefinitionMetadataStylesTargetArrowShape = "triangle-backcurve"
	RelationshipDefinitionMetadataStylesTargetArrowShapeTriangleCross     RelationshipDefinitionMetadataStylesTargetArrowShape = "triangle-cross"
	RelationshipDefinitionMetadataStylesTargetArrowShapeTriangleTee       RelationshipDefinitionMetadataStylesTargetArrowShape = "triangle-tee"
	RelationshipDefinitionMetadataStylesTargetArrowShapeVee               RelationshipDefinitionMetadataStylesTargetArrowShape = "vee"
)

// Defines values for RelationshipDefinitionMetadataStylesTextTransform.
const (
	Lowercase RelationshipDefinitionMetadataStylesTextTransform = "lowercase"
	None      RelationshipDefinitionMetadataStylesTextTransform = "none"
	Uppercase RelationshipDefinitionMetadataStylesTextTransform = "uppercase"
)

// Defines values for RelationshipDefinitionSelectorsPatchStrategy.
const (
	Add       RelationshipDefinitionSelectorsPatchStrategy = "add"
	Copy      RelationshipDefinitionSelectorsPatchStrategy = "copy"
	Merge     RelationshipDefinitionSelectorsPatchStrategy = "merge"
	Move      RelationshipDefinitionSelectorsPatchStrategy = "move"
	Remove    RelationshipDefinitionSelectorsPatchStrategy = "remove"
	Strategic RelationshipDefinitionSelectorsPatchStrategy = "strategic"
	Test      RelationshipDefinitionSelectorsPatchStrategy = "test"
)

// MatchSelector Match configuration for selector
type MatchSelector struct {
	// From The from of the matchselector.
	From *[]MatchSelectorItem `json:"from,omitempty" yaml:"from,omitempty"`

	// Refs The refs of the matchselector.
	Refs *[][]string `json:"refs,omitempty" yaml:"refs,omitempty"`

	// To The to of the matchselector.
	To *[]MatchSelectorItem `json:"to,omitempty" yaml:"to,omitempty"`
}

// MatchSelectorItem Match selector item for binding between nodes
type MatchSelectorItem struct {
	// Id A Universally Unique Identifier used to uniquely identify entities in Meshery. The UUID core definition is used across different schemas.
	ID *core.Uuid `json:"id" yaml:"id,omitempty"`

	// Kind Kind of the resource.
	Kind       string      `json:"kind" yaml:"kind"`
	MutatedRef *MutatedRef `json:"mutatedRef,omitempty" yaml:"mutatedRef,omitempty"`

	// MutatorRef JSON ref to value from where patch should be applied.
	MutatorRef *MutatorRef `json:"mutatorRef,omitempty" yaml:"mutatorRef,omitempty"`
}

// MutatedRef defines model for MutatedRef.
type MutatedRef = [][]string

// MutatorRef JSON ref to value from where patch should be applied.
type MutatorRef = [][]string

// RelationshipDefinition Relationships define the nature of interaction between interconnected components in Meshery. The combination of relationship properties kind, type, and subtype characterize various genealogical relations among and between components. Relationships have selectors, selector sets, metadata, and optional parameters. Learn more at https://docs.meshery.io/concepts/logical/relationships.
type RelationshipDefinition struct {
	// Id A Universally Unique Identifier used to uniquely identify entities in Meshery. The UUID core definition is used across different schemas.
	ID core.Uuid `json:"id" yaml:"id"`

	// Capabilities Capabilities associated with the relationship.
	Capabilities *[]capabilityv1beta1.Capability `gorm:"type:bytes;serializer:json" json:"capabilities,omitempty" yaml:"capabilities"`

	// EvaluationQuery Optional. Assigns the policy to be used for the evaluation of the relationship. Deprecation Notice: In the future, this property is either to be removed or to it is to be an array of optional policy $refs.
	EvaluationQuery *string `json:"evaluationQuery" yaml:"evaluationQuery"`

	// Kind Kind of the Relationship. Learn more about relationships - https://docs.meshery.io/concepts/logical/relationships.
	Kind RelationshipDefinitionKind `json:"kind" yaml:"kind"`

	// RelationshipMetadata Metadata contains additional information associated with the Relationship.
	RelationshipMetadata *RelationshipMetadata `gorm:"column:metadata;type:bytes;serializer:json" json:"metadata,omitempty" yaml:"metadata"`

	// Model Reference to the specific registered model to which the component belongs and from which model version, category, and other properties may be referenced. Learn more at https://docs.meshery.io/concepts/models
	Model modelv1beta1.ModelReference `gorm:"type:bytes;serializer:json" json:"model" yaml:"model"`

	// ModelId A Universally Unique Identifier used to uniquely identify entities in Meshery. The UUID core definition is used across different schemas.
	ModelId *core.Uuid `gorm:"index:idx_relationship_definition_dbs_model_id,column:model_id" json:"-" yaml:"modelId,omitempty"`

	// SchemaVersion API version of the object, optionally prefixed with an API group (e.g. "group.example.io/v1beta1" or bare "v1beta1").
	SchemaVersion core.VersionString `json:"schemaVersion" yaml:"schemaVersion"`

	// Selectors Selectors are organized as an array, with each item containing a distinct set of selectors that share a common functionality. This structure allows for flexibility in defining relationships, even when different components are involved.
	Selectors *SelectorSet `gorm:"type:bytes;serializer:json" json:"selectors,omitempty" yaml:"selectors,omitempty"`

	// SubType Most granular unit of relationship classification. The combination of Kind, Type and SubType together uniquely identify a Relationship.
	SubType string `json:"subType" yaml:"subType"`

	// Status Status of the relationship.
	Status *RelationshipDefinitionStatus `json:"status" yaml:"status"`

	// RelationshipType Classification of relationships. Used to group relationships similar in nature.
	RelationshipType string `gorm:"column:type" json:"type" yaml:"type"`

	// Version A valid semantic version string between 5 and 100 characters. The pattern allows for a major.minor.patch version followed by an optional pre-release tag like '-alpha' or '-beta.2' and an optional build metadata tag like '+build.1'.
	Version core.SemverString `json:"version" yaml:"version"`
}

// RelationshipDefinitionKind Kind of the Relationship. Learn more about relationships - https://docs.meshery.io/concepts/logical/relationships.
type RelationshipDefinitionKind string

// RelationshipDefinitionStatus Status of the relationship.
type RelationshipDefinitionStatus string

// RelationshipDefinitionMetadataStyles Visualization styles for a relationship
type RelationshipDefinitionMetadataStyles struct {
	// ArrowScale Scaling for the arrow size.
	ArrowScale *float32 `json:"arrowScale,omitempty" yaml:"arrowScale,omitempty"`

	// Color The color of the element's label. Colours may be specified by name (e.g. red), hex (e.g.
	Color *string `json:"color,omitempty" yaml:"color,omitempty"`

	// CurveStyle The curving method used to separate two or more edges between two nodes; may be haystack (very fast, bundled straight edges for which loops and compounds are unsupported), straight (straight edges with all arrows supported), bezier (bundled curved edges), unbundled-bezier (curved edges for use with manual control points), segments (a series of straight lines), taxi (right-angled lines, hierarchically bundled). Note that haystack edges work best with ellipse, rectangle, or similar nodes. Smaller node shapes, like triangle, will not be as aesthetically pleasing. Also note that edge endpoint arrows are unsupported for haystack edges.
	CurveStyle *RelationshipDefinitionMetadataStylesCurveStyle `json:"curveStyle,omitempty" yaml:"curveStyle,omitempty"`

	// EdgeAnimation The animation to use for the edge. Can be like 'marching-ants' , 'blink' , 'moving-gradient',etc .
	EdgeAnimation *string `json:"edgeAnimation,omitempty" yaml:"edgeAnimation,omitempty"`

	// FontFamily A comma-separated list of font names to use on the label text.
	FontFamily *string `json:"fontFamily,omitempty" yaml:"fontFamily,omitempty"`

	// FontSize The size of the label text.
	FontSize *string `json:"fontSize,omitempty" yaml:"fontSize,omitempty"`

	// FontStyle A CSS font style to be applied to the label text.
	FontStyle *string `json:"fontStyle,omitempty" yaml:"fontStyle,omitempty"`

	// FontWeight A CSS font weight to be applied to the label text.
	FontWeight *string `json:"fontWeight,omitempty" yaml:"fontWeight,omitempty"`

	// Label The text to display for an element's label. Can give a path, e.g. data(id) will label with the elements id
	Label *string `json:"label,omitempty" yaml:"label,omitempty"`

	// LineCap The cap style of the edge's line; may be butt (default), round, or square. The cap may or may not be visible, depending on the shape of the node and the relative size of the node and edge. Caps other than butt extend beyond the specified endpoint of the edge.
	LineCap *RelationshipDefinitionMetadataStylesLineCap `json:"lineCap,omitempty" yaml:"lineCap,omitempty"`

	// LineColor The colour of the edge's line. Colours may be specified by name (e.g. red), hex (e.g.
	LineColor *string `json:"lineColor,omitempty" yaml:"lineColor,omitempty"`

	// LineOpacity The opacity of the edge's line and arrow. Useful if you wish to have a separate opacity for the edge label versus the edge line. Note that the opacity value of the edge element affects the effective opacity of its line and label subcomponents.
	LineOpacity *float32 `json:"lineOpacity,omitempty" yaml:"lineOpacity,omitempty"`

	// LineStyle The style of the edge's line.
	LineStyle *RelationshipDefinitionMetadataStylesLineStyle `json:"lineStyle,omitempty" yaml:"lineStyle,omitempty"`

	// MidTargetArrowColor The colour of the edge's source arrow. Colours may be specified by name (e.g. red), hex (e.g.
	MidTargetArrowColor *string `json:"midTargetArrowColor,omitempty" yaml:"midTargetArrowColor,omitempty"`

	// MidTargetArrowFill The fill state of the edge's source arrow
	MidTargetArrowFill *RelationshipDefinitionMetadataStylesMidTargetArrowFill `json:"midTargetArrowFill,omitempty" yaml:"midTargetArrowFill,omitempty"`

	// MidTargetArrowShape The shape of the edge's source arrow
	MidTargetArrowShape *RelationshipDefinitionMetadataStylesMidTargetArrowShape `json:"midTargetArrowShape,omitempty" yaml:"midTargetArrowShape,omitempty"`

	// Opacity The opacity of the element, ranging from 0 to 1. Note that the opacity of a compound node parent affects the effective opacity of its children.See https://js.cytoscape.org/#style/visibility
	Opacity *float32 `json:"opacity,omitempty" yaml:"opacity,omitempty"`

	// PrimaryColor Primary color of the component used for UI representation.
	PrimaryColor string `json:"primaryColor" yaml:"primaryColor"`

	// SecondaryColor Secondary color of the entity used for UI representation.
	SecondaryColor *string `json:"secondaryColor,omitempty" yaml:"secondaryColor,omitempty"`

	// SourceLabel The text to display for an edge's source label. Can give a path, e.g. data(id) will label with the elements id
	SourceLabel *string `json:"sourceLabel,omitempty" yaml:"sourceLabel,omitempty"`

	// SvgColor Colored SVG of the entity used for UI representation on light background.
	SvgColor string `json:"svgColor" yaml:"svgColor"`

	// SvgComplete Complete SVG of the entity used for UI representation, often inclusive of background.
	SvgComplete *string `json:"svgComplete,omitempty" yaml:"svgComplete,omitempty"`

	// SvgWhite White SVG of the entity used for UI representation on dark background.
	SvgWhite string `json:"svgWhite" yaml:"svgWhite"`

	// TargetArrowColor The colour of the edge's source arrow. Colours may be specified by name (e.g. red), hex (e.g.
	TargetArrowColor *string `json:"targetArrowColor,omitempty" yaml:"targetArrowColor,omitempty"`

	// TargetArrowFill The fill state of the edge's source arrow
	TargetArrowFill *RelationshipDefinitionMetadataStylesTargetArrowFill `json:"targetArrowFill,omitempty" yaml:"targetArrowFill,omitempty"`

	// TargetArrowShape The shape of the edge's source arrow
	TargetArrowShape *RelationshipDefinitionMetadataStylesTargetArrowShape `json:"targetArrowShape,omitempty" yaml:"targetArrowShape,omitempty"`

	// TargetLabel The text to display for an edge's target label. Can give a path, e.g. data(id) will label with the elements id
	TargetLabel *string `json:"targetLabel,omitempty" yaml:"targetLabel,omitempty"`

	// TextOpacity The opacity of the label text, including its outline.
	TextOpacity *float32 `json:"textOpacity,omitempty" yaml:"textOpacity,omitempty"`

	// TextTransform A transformation to apply to the label text
	TextTransform *RelationshipDefinitionMetadataStylesTextTransform `json:"textTransform,omitempty" yaml:"textTransform,omitempty"`

	// ZIndex An integer value that affects the relative draw order of elements. In general, an element with a higher z-index will be drawn on top of an element with a lower z-index. Note that edges are under nodes despite z-index.
	ZIndex *int `json:"zIndex,omitempty" yaml:"zIndex,omitempty"`
}

// RelationshipDefinitionMetadataStylesArrowShape The shape of the edge's arrow
type RelationshipDefinitionMetadataStylesArrowShape string

// RelationshipDefinitionMetadataStylesCurveStyle The curving method used to separate two or more edges between two nodes; may be haystack (very fast, bundled straight edges for which loops and compounds are unsupported), straight (straight edges with all arrows supported), bezier (bundled curved edges), unbundled-bezier (curved edges for use with manual control points), segments (a series of straight lines), taxi (right-angled lines, hierarchically bundled). Note that haystack edges work best with ellipse, rectangle, or similar nodes. Smaller node shapes, like triangle, will not be as aesthetically pleasing. Also note that edge endpoint arrows are unsupported for haystack edges.
type RelationshipDefinitionMetadataStylesCurveStyle string

// RelationshipDefinitionMetadataStylesLineCap The cap style of the edge's line; may be butt (default), round, or square. The cap may or may not be visible, depending on the shape of the node and the relative size of the node and edge. Caps other than butt extend beyond the specified endpoint of the edge.
type RelationshipDefinitionMetadataStylesLineCap string

// RelationshipDefinitionMetadataStylesLineStyle The style of the edge's line.
type RelationshipDefinitionMetadataStylesLineStyle string

// RelationshipDefinitionMetadataStylesMidTargetArrowFill The fill state of the edge's source arrow
type RelationshipDefinitionMetadataStylesMidTargetArrowFill string

// RelationshipDefinitionMetadataStylesMidTargetArrowShape The shape of the edge's source arrow
type RelationshipDefinitionMetadataStylesMidTargetArrowShape string

// RelationshipDefinitionMetadataStylesTargetArrowFill The fill state of the edge's source arrow
type RelationshipDefinitionMetadataStylesTargetArrowFill string

// RelationshipDefinitionMetadataStylesTargetArrowShape The shape of the edge's source arrow
type RelationshipDefinitionMetadataStylesTargetArrowShape string

// RelationshipDefinitionMetadataStylesTextTransform A transformation to apply to the label text
type RelationshipDefinitionMetadataStylesTextTransform string

// RelationshipDefinitionSelectorsPatch Patch configuration for the selector
type RelationshipDefinitionSelectorsPatch struct {
	MutatedRef *MutatedRef `json:"mutatedRef,omitempty" yaml:"mutatedRef,omitempty"`

	// MutatorRef JSON ref to value from where patch should be applied.
	MutatorRef *MutatorRef `json:"mutatorRef,omitempty" yaml:"mutatorRef,omitempty"`

	// PatchStrategy patchStrategy allows you to make specific changes to a resource using a standard JSON Patch format (RFC 6902).
	//
	// add: Inserts a value into an array or adds a member to an object.
	// merge: Combines the values of the target location with the values from the patch. If the target location doesn't exist, it is created.
	// strategic: specific to Kubernetes and understands the structure of Kubernetes objects.
	// remove: Removes a value.
	// copy: Copies a value from one location to another.
	// move: Moves a value from one location to another.
	// test: Tests that a value at the target location is equal to a specified value.
	PatchStrategy *RelationshipDefinitionSelectorsPatchStrategy `json:"patchStrategy,omitempty" yaml:"patchStrategy,omitempty"`
}

// RelationshipDefinitionSelectorsPatchStrategy patchStrategy allows you to make specific changes to a resource using a standard JSON Patch format (RFC 6902).
//
// add: Inserts a value into an array or adds a member to an object.
// merge: Combines the values of the target location with the values from the patch. If the target location doesn't exist, it is created.
// strategic: specific to Kubernetes and understands the structure of Kubernetes objects.
// remove: Removes a value.
// copy: Copies a value from one location to another.
// move: Moves a value from one location to another.
// test: Tests that a value at the target location is equal to a specified value.
type RelationshipDefinitionSelectorsPatchStrategy string

// RelationshipMetadata Metadata contains additional information associated with the Relationship.
type RelationshipMetadata struct {
	// Description Characterization of the meaning of the relationship and its relevance to both Meshery and entities under management.
	Description *string `json:"description" yaml:"description"`

	// IsAnnotation Indicates whether the relationship should be treated as a logical representation only
	IsAnnotation *bool `json:"isAnnotation" yaml:"isAnnotation"`

	// Styles Visualization styles for a relationship
	Styles               *RelationshipDefinitionMetadataStyles `json:"styles" yaml:"styles,omitempty"`
	AdditionalProperties map[string]interface{}                `json:"-" yaml:"-"`
}

// Selector Describes the component(s) which are involved in the relationship along with a set of actions to perform upon selection match.
type Selector struct {
	// From Describes the component(s) which are involved in the relationship along with a set of actions to perform upon selection match.
	From []SelectorItem `json:"from" yaml:"from"`

	// To Describes the component(s) which are involved in the relationship along with a set of actions to perform upon selection match.
	To []SelectorItem `json:"to" yaml:"to"`
}

// SelectorItem Optional fields that are a part of the selector. Absence of a field has an implied * meaning.
type SelectorItem struct {
	// Id A Universally Unique Identifier used to uniquely identify entities in Meshery. The UUID core definition is used across different schemas.
	ID *core.Uuid `json:"id" yaml:"id,omitempty"`

	// Kind Kind of the resource.
	Kind *string `json:"kind" yaml:"kind"`

	// Match Match configuration for selector
	Match *MatchSelector `json:"match,omitempty" yaml:"match,omitempty"`

	// MatchStrategyMatrix Match strategy matrix for the selector
	MatchStrategyMatrix *[][]string `json:"matchStrategyMatrix" yaml:"matchStrategyMatrix"`

	// Model Reference to the specific registered model to which the component belongs and from which model version, category, and other properties may be referenced. Learn more at https://docs.meshery.io/concepts/models
	Model *modelv1beta1.ModelReference `json:"model,omitempty" yaml:"model,omitempty"`

	// RelationshipDefinitionSelectorsPatch Patch configuration for the selector
	RelationshipDefinitionSelectorsPatch *RelationshipDefinitionSelectorsPatch `json:"patch" yaml:"patch,omitempty"`
}

// SelectorSet Selectors are organized as an array, with each item containing a distinct set of selectors that share a common functionality. This structure allows for flexibility in defining relationships, even when different components are involved.
type SelectorSet = []SelectorSetItem

// SelectorSetItem Optional selectors used to match Components. Absence of a selector means that it is applied to all Components.
type SelectorSetItem struct {
	// Allow Describes the component(s) which are involved in the relationship along with a set of actions to perform upon selection match.
	Allow Selector `json:"allow" yaml:"allow"`

	// Deny Describes the component(s) which are involved in the relationship along with a set of actions to perform upon selection match.
	Deny *Selector `json:"deny,omitempty" yaml:"deny,omitempty"`
}

// Getter for additional properties for RelationshipMetadata. Returns the specified
// element and whether it was found
func (a RelationshipMetadata) Get(fieldName string) (value interface{}, found bool) {
	if a.AdditionalProperties != nil {
		value, found = a.AdditionalProperties[fieldName]
	}
	return
}

// Setter for additional properties for RelationshipMetadata
func (a *RelationshipMetadata) Set(fieldName string, value interface{}) {
	if a.AdditionalProperties == nil {
		a.AdditionalProperties = make(map[string]interface{})
	}
	a.AdditionalProperties[fieldName] = value
}

// Override default JSON handling for RelationshipMetadata to handle AdditionalProperties
func (a *RelationshipMetadata) UnmarshalJSON(b []byte) error {
	object := make(map[string]json.RawMessage)
	err := json.Unmarshal(b, &object)
	if err != nil {
		return err
	}

	if raw, found := object["description"]; found {
		err = json.Unmarshal(raw, &a.Description)
		if err != nil {
			return fmt.Errorf("error reading 'description': %w", err)
		}
		delete(object, "description")
	}

	if raw, found := object["isAnnotation"]; found {
		err = json.Unmarshal(raw, &a.IsAnnotation)
		if err != nil {
			return fmt.Errorf("error reading 'isAnnotation': %w", err)
		}
		delete(object, "isAnnotation")
	}

	if raw, found := object["styles"]; found {
		err = json.Unmarshal(raw, &a.Styles)
		if err != nil {
			return fmt.Errorf("error reading 'styles': %w", err)
		}
		delete(object, "styles")
	}

	if len(object) != 0 {
		a.AdditionalProperties = make(map[string]interface{})
		for fieldName, fieldBuf := range object {
			var fieldVal interface{}
			err := json.Unmarshal(fieldBuf, &fieldVal)
			if err != nil {
				return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
			}
			a.AdditionalProperties[fieldName] = fieldVal
		}
	}
	return nil
}

// Override default JSON handling for RelationshipMetadata to handle AdditionalProperties
func (a RelationshipMetadata) MarshalJSON() ([]byte, error) {
	var err error
	object := make(map[string]json.RawMessage)

	if a.Description != nil {
		object["description"], err = json.Marshal(a.Description)
		if err != nil {
			return nil, fmt.Errorf("error marshaling 'description': %w", err)
		}
	}

	if a.IsAnnotation != nil {
		object["isAnnotation"], err = json.Marshal(a.IsAnnotation)
		if err != nil {
			return nil, fmt.Errorf("error marshaling 'isAnnotation': %w", err)
		}
	}

	if a.Styles != nil {
		object["styles"], err = json.Marshal(a.Styles)
		if err != nil {
			return nil, fmt.Errorf("error marshaling 'styles': %w", err)
		}
	}

	for fieldName, field := range a.AdditionalProperties {
		object[fieldName], err = json.Marshal(field)
		if err != nil {
			return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err)
		}
	}
	return json.Marshal(object)
}
