// Package model 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 model

import (
	"encoding/json"
	"fmt"

	core "github.com/meshery/schemas/models/core"
	capabilityv1beta1 "github.com/meshery/schemas/models/v1beta1/capability"
	categoryv1beta1 "github.com/meshery/schemas/models/v1beta1/category"
	connectionv1beta1 "github.com/meshery/schemas/models/v1beta1/connection"
	subcategoryv1beta1 "github.com/meshery/schemas/models/v1beta1/subcategory"
	"github.com/oapi-codegen/runtime"
	openapi_types "github.com/oapi-codegen/runtime/types"
)

// Defines values for ImportRequestUploadType.
const (
	Csv       ImportRequestUploadType = "csv"
	File      ImportRequestUploadType = "file"
	Url       ImportRequestUploadType = "url"
	UrlImport ImportRequestUploadType = "urlImport"
)

// Defines values for ModelDefinitionStatus.
const (
	Duplicate ModelDefinitionStatus = "duplicate"
	Enabled   ModelDefinitionStatus = "enabled"
	Ignored   ModelDefinitionStatus = "ignored"
)

// ImportBody defines model for ImportBody.
type ImportBody struct {
	union json.RawMessage
}

// ImportBody0 defines model for .
type ImportBody0 struct {
	// FileName Name of the file being uploaded.
	FileName string `json:"fileName" yaml:"fileName"`

	// ModelFile Supported model file formats are: .tar, .tar.gz, and .tgz. See [Import Models Documentation](https://docs.meshery.io/guides/configuration-management/importing-models#import-models-using-meshery-ui) for details
	ModelFile string `json:"modelFile" yaml:"modelFile"`
}

// ImportBody1 defines model for .
type ImportBody1 struct {
	// Url A direct URL to a single model file, for example: https://raw.github.com/your-model-file.tar. Supported model file formats are: .tar, .tar.gz, and .tgz. \n\nFor bulk import of your model use the GitHub connection or CSV files. See [Import Models Documentation](https://docs.meshery.io/guides/configuration-management/importing-models#import-models-using-meshery-ui) for details
	Url string `json:"url" yaml:"url"`
}

// ImportBody2 defines model for .
type ImportBody2 struct {
	// ComponentCsv Upload a CSV file containing component definitions
	ComponentCsv openapi_types.File `json:"componentCsv" yaml:"componentCsv"`

	// ModelCsv Upload a CSV file containing model definitions
	ModelCsv openapi_types.File `json:"modelCsv" yaml:"modelCsv"`

	// RelationshipCsv Upload a CSV file containing relationship definitions
	RelationshipCsv openapi_types.File `json:"relationshipCsv" yaml:"relationshipCsv"`
}

// ImportBody3 defines model for .
type ImportBody3 struct {
	// Url URI to the source code or package of the model.
	Url string `json:"url" yaml:"url"`
}

// ImportRequest defines model for ImportRequest.
type ImportRequest struct {
	ImportBody ImportBody `json:"importBody" yaml:"importBody"`

	// Register The register of the importrequest.
	Register bool `json:"register" yaml:"register"`

	// UploadType Choose the method you prefer to upload your model file. Select 'File Import' or 'CSV Import' if you have the file on your local system or 'URL Import' if you have the file hosted online.
	UploadType ImportRequestUploadType `json:"uploadType" yaml:"uploadType"`
}

// ImportRequestUploadType Choose the method you prefer to upload your model file. Select 'File Import' or 'CSV Import' if you have the file on your local system or 'URL Import' if you have the file hosted online.
type ImportRequestUploadType string

// MeshModelModelsPage defines model for MeshModelModelsPage.
type MeshModelModelsPage struct {
	// Models The models matching the list-endpoint query.
	Models *[]ModelDefinition `json:"models,omitempty" yaml:"models,omitempty"`

	// Page Current page number of the result set.
	Page *int `json:"page,omitempty" yaml:"page,omitempty"`

	// PageSize Number of items per page.
	PageSize *int `json:"page_size,omitempty" yaml:"page_size,omitempty"`

	// TotalCount Total number of items available.
	TotalCount *int `json:"total_count,omitempty" yaml:"total_count,omitempty"`
}

// Model Registrant-defined data associated with the model. Properties pertain to the software being managed (e.g. Kubernetes v1.31).
type Model struct {
	// 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"`
}

// ModelDefinition Meshery Models serve as a portable unit of packaging to define managed entities, their relationships, and capabilities.
type ModelDefinition 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"`

	// 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"`

	// 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"`

	// Name The unique name for the model within the scope of a registrant.
	Name string `json:"name" yaml:"name"`

	// DisplayName Human-readable name for the model.
	DisplayName string `json:"displayName" yaml:"displayName"`

	// Description Description of the model.
	Description string `json:"description,omitempty" yaml:"description,omitempty"`

	// Status Status of model, including:
	// - duplicate: this component is a duplicate of another. The component that is to be the canonical reference and that is duplicated by other components should not be assigned the 'duplicate' status.
	// - maintenance: model is unavailable for a period of time.
	// - enabled: model is available for use for all users of this Meshery Server.
	// - ignored: model is unavailable for use for all users of this Meshery Server.
	Status ModelDefinitionStatus `json:"status" yaml:"status"`

	// CategoryId A Universally Unique Identifier used to uniquely identify entities in Meshery. The UUID core definition is used across different schemas.
	CategoryId core.Uuid `gorm:"categoryID" json:"-" yaml:"-"`

	// Registrant Meshery Connections are managed and unmanaged resources that either through discovery or manual entry are tracked by Meshery. Learn more at https://docs.meshery.io/concepts/logical/connections
	Registrant connectionv1beta1.Connection `gorm:"foreignKey:RegistrantId;references:ID" json:"registrant" yaml:"registrant"`

	// RegistrantId A Universally Unique Identifier used to uniquely identify entities in Meshery. The UUID core definition is used across different schemas.
	RegistrantId core.Uuid `gorm:"column:connection_id" json:"connection_id" yaml:"connection_id"`

	// Category Category of the model.
	Category categoryv1beta1.CategoryDefinition `gorm:"foreignKey:CategoryId;references:ID" json:"category" yaml:"category"`

	// SubCategory Sub category of the model determines the secondary grouping.
	SubCategory subcategoryv1beta1.SubCategoryDefinition `json:"subCategory" yaml:"subCategory"`

	// Metadata Metadata containing additional information associated with the model.
	Metadata *ModelDefinition_Metadata `gorm:"type:bytes;serializer:json" json:"metadata" yaml:"metadata"`

	// Model Registrant-defined data associated with the model. Properties pertain to the software being managed (e.g. Kubernetes v1.31).
	Model Model `gorm:"type:bytes;serializer:json" json:"model" yaml:"model"`

	// ComponentsCount Number of components associated with the model.
	ComponentsCount int `gorm:"-" json:"components_count" yaml:"components_count"`

	// RelationshipsCount Number of relationships associated with the model.
	RelationshipsCount int `gorm:"-" json:"relationships_count" yaml:"relationships_count"`

	// CreatedAt Timestamp when the resource was created.
	CreatedAt core.CreatedAt `db:"created_at" json:"created_at,omitempty" yaml:"created_at,omitempty"`

	// UpdatedAt Timestamp when the resource was updated.
	UpdatedAt core.UpdatedAt `db:"updated_at" json:"updated_at,omitempty" yaml:"updated_at,omitempty"`

	// Components The components of the model.
	Components interface{} `gorm:"-" json:"components" yaml:"components"`

	// Relationships The relationships of the model.
	Relationships interface{} `gorm:"-" json:"relationships" yaml:"relationships"`
}

// ModelDefinitionStatus Status of model, including:
// - duplicate: this component is a duplicate of another. The component that is to be the canonical reference and that is duplicated by other components should not be assigned the 'duplicate' status.
// - maintenance: model is unavailable for a period of time.
// - enabled: model is available for use for all users of this Meshery Server.
// - ignored: model is unavailable for use for all users of this Meshery Server.
type ModelDefinitionStatus string

// ModelDefinition_Metadata Metadata containing additional information associated with the model.
type ModelDefinition_Metadata struct {
	// Capabilities Capabilities associated with the model
	Capabilities *[]capabilityv1beta1.Capability `json:"capabilities,omitempty" yaml:"capabilities,omitempty"`

	// IsAnnotation Indicates whether the model and its entities should be treated as deployable entities or as logical representations.
	IsAnnotation *bool `json:"isAnnotation" yaml:"isAnnotation"`

	// PrimaryColor Primary color associated with the model.
	PrimaryColor *string `json:"primaryColor" yaml:"primaryColor"`

	// SecondaryColor Secondary color associated with the model.
	SecondaryColor *string `json:"secondaryColor" yaml:"secondaryColor"`

	// SvgWhite SVG representation of the model in white color.
	SvgWhite string `json:"svgWhite" yaml:"svgWhite"`

	// SvgColor SVG representation of the model in colored format.
	SvgColor string `json:"svgColor" yaml:"svgColor"`

	// SvgComplete SVG representation of the complete model.
	SvgComplete *string `json:"svgComplete" yaml:"svgComplete"`

	// Shape The shape of the node's body. Note that each shape fits within the specified width and height, and so you may have to adjust width and height if you desire an equilateral shape (i.e. width !== height for several equilateral shapes)
	Shape                *core.Shape    `json:"shape,omitempty" yaml:"shape,omitempty"`
	AdditionalProperties map[string]interface{} `json:"-" yaml:"-"`
}

// ModelReference 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
type ModelReference struct {
	// DisplayName Human-readable name for the model.
	DisplayName string `json:"displayName" yaml:"displayName"`

	// 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"`

	// Model Registrant-defined data associated with the model. Properties pertain to the software being managed (e.g. Kubernetes v1.31).
	Model Model `json:"model" yaml:"model"`

	// Name The unique name for the model within the scope of a registrant.
	Name       string              `json:"name" yaml:"name"`
	Registrant RegistrantReference `json:"registrant" yaml:"registrant"`

	// 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"`
}

// RegistrantReference defines model for RegistrantReference.
type RegistrantReference struct {
	// Kind Kind of the registrant.
	Kind string `json:"kind" yaml:"kind"`
}

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

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

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

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

	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["primaryColor"]; found {
		err = json.Unmarshal(raw, &a.PrimaryColor)
		if err != nil {
			return fmt.Errorf("error reading 'primaryColor': %w", err)
		}
		delete(object, "primaryColor")
	}

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

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

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

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

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

	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 ModelDefinition_Metadata to handle AdditionalProperties
func (a ModelDefinition_Metadata) MarshalJSON() ([]byte, error) {
	var err error
	object := make(map[string]json.RawMessage)

	if a.Capabilities != nil {
		object["capabilities"], err = json.Marshal(a.Capabilities)
		if err != nil {
			return nil, fmt.Errorf("error marshaling 'capabilities': %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.PrimaryColor != nil {
		object["primaryColor"], err = json.Marshal(a.PrimaryColor)
		if err != nil {
			return nil, fmt.Errorf("error marshaling 'primaryColor': %w", err)
		}
	}

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

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

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

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

	if a.Shape != nil {
		object["shape"], err = json.Marshal(a.Shape)
		if err != nil {
			return nil, fmt.Errorf("error marshaling 'shape': %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)
}

// AsImportBody0 returns the union data inside the ImportBody as a ImportBody0
func (t ImportBody) AsImportBody0() (ImportBody0, error) {
	var body ImportBody0
	err := json.Unmarshal(t.union, &body)
	return body, err
}

// FromImportBody0 overwrites any union data inside the ImportBody as the provided ImportBody0
func (t *ImportBody) FromImportBody0(v ImportBody0) error {
	b, err := json.Marshal(v)
	t.union = b
	return err
}

// MergeImportBody0 performs a merge with any union data inside the ImportBody, using the provided ImportBody0
func (t *ImportBody) MergeImportBody0(v ImportBody0) error {
	b, err := json.Marshal(v)
	if err != nil {
		return err
	}

	merged, err := runtime.JSONMerge(t.union, b)
	t.union = merged
	return err
}

// AsImportBody1 returns the union data inside the ImportBody as a ImportBody1
func (t ImportBody) AsImportBody1() (ImportBody1, error) {
	var body ImportBody1
	err := json.Unmarshal(t.union, &body)
	return body, err
}

// FromImportBody1 overwrites any union data inside the ImportBody as the provided ImportBody1
func (t *ImportBody) FromImportBody1(v ImportBody1) error {
	b, err := json.Marshal(v)
	t.union = b
	return err
}

// MergeImportBody1 performs a merge with any union data inside the ImportBody, using the provided ImportBody1
func (t *ImportBody) MergeImportBody1(v ImportBody1) error {
	b, err := json.Marshal(v)
	if err != nil {
		return err
	}

	merged, err := runtime.JSONMerge(t.union, b)
	t.union = merged
	return err
}

// AsImportBody2 returns the union data inside the ImportBody as a ImportBody2
func (t ImportBody) AsImportBody2() (ImportBody2, error) {
	var body ImportBody2
	err := json.Unmarshal(t.union, &body)
	return body, err
}

// FromImportBody2 overwrites any union data inside the ImportBody as the provided ImportBody2
func (t *ImportBody) FromImportBody2(v ImportBody2) error {
	b, err := json.Marshal(v)
	t.union = b
	return err
}

// MergeImportBody2 performs a merge with any union data inside the ImportBody, using the provided ImportBody2
func (t *ImportBody) MergeImportBody2(v ImportBody2) error {
	b, err := json.Marshal(v)
	if err != nil {
		return err
	}

	merged, err := runtime.JSONMerge(t.union, b)
	t.union = merged
	return err
}

// AsImportBody3 returns the union data inside the ImportBody as a ImportBody3
func (t ImportBody) AsImportBody3() (ImportBody3, error) {
	var body ImportBody3
	err := json.Unmarshal(t.union, &body)
	return body, err
}

// FromImportBody3 overwrites any union data inside the ImportBody as the provided ImportBody3
func (t *ImportBody) FromImportBody3(v ImportBody3) error {
	b, err := json.Marshal(v)
	t.union = b
	return err
}

// MergeImportBody3 performs a merge with any union data inside the ImportBody, using the provided ImportBody3
func (t *ImportBody) MergeImportBody3(v ImportBody3) error {
	b, err := json.Marshal(v)
	if err != nil {
		return err
	}

	merged, err := runtime.JSONMerge(t.union, b)
	t.union = merged
	return err
}

func (t ImportBody) MarshalJSON() ([]byte, error) {
	b, err := t.union.MarshalJSON()
	return b, err
}

func (t *ImportBody) UnmarshalJSON(b []byte) error {
	err := t.union.UnmarshalJSON(b)
	return err
}
