// Code generated by go-swagger; DO NOT EDIT.

// Copyright Authors of Cilium
// SPDX-License-Identifier: Apache-2.0

package models

import (
	"context"
	"encoding/json"
	stderrors "errors"
	"strconv"

	"github.com/go-openapi/errors"
	"github.com/go-openapi/strfmt"
	"github.com/go-openapi/swag/jsonutils"
	"github.com/go-openapi/swag/typeutils"
	"github.com/go-openapi/validate"
)

// BgpRoutePolicyStatement Single BGP route policy statement
//
// swagger:model BgpRoutePolicyStatement
type BgpRoutePolicyStatement struct {

	// List of BGP standard community values to be added to the matched route
	AddCommunities []string `json:"add-communities"`

	// List of BGP large community values to be added to the matched route
	AddLargeCommunities []string `json:"add-large-communities"`

	// Matches any of the provided address families. If empty matches all address families.
	MatchFamilies []*BgpFamily `json:"match-families"`

	// Matches BGP neighbor IP address with the provided match rules
	MatchNeighbors *BgpRoutePolicyNeighborMatch `json:"match-neighbors,omitempty"`

	// Matches CIDR prefix with the provided match rules
	MatchPrefixes *BgpRoutePolicyPrefixMatch `json:"match-prefixes,omitempty"`

	// BGP nexthop action
	Nexthop *BgpRoutePolicyNexthopAction `json:"nexthop,omitempty"`

	// RIB processing action taken on the matched route
	// Enum: ["none","accept","reject"]
	RouteAction string `json:"route-action,omitempty"`

	// BGP local preference value to be set on the matched route
	SetLocalPreference int64 `json:"set-local-preference,omitempty"`
}

// Validate validates this bgp route policy statement
func (m *BgpRoutePolicyStatement) Validate(formats strfmt.Registry) error {
	var res []error

	if err := m.validateMatchFamilies(formats); err != nil {
		res = append(res, err)
	}

	if err := m.validateMatchNeighbors(formats); err != nil {
		res = append(res, err)
	}

	if err := m.validateMatchPrefixes(formats); err != nil {
		res = append(res, err)
	}

	if err := m.validateNexthop(formats); err != nil {
		res = append(res, err)
	}

	if err := m.validateRouteAction(formats); err != nil {
		res = append(res, err)
	}

	if len(res) > 0 {
		return errors.CompositeValidationError(res...)
	}
	return nil
}

func (m *BgpRoutePolicyStatement) validateMatchFamilies(formats strfmt.Registry) error {
	if typeutils.IsZero(m.MatchFamilies) { // not required
		return nil
	}

	for i := 0; i < len(m.MatchFamilies); i++ {
		if typeutils.IsZero(m.MatchFamilies[i]) { // not required
			continue
		}

		if m.MatchFamilies[i] != nil {
			if err := m.MatchFamilies[i].Validate(formats); err != nil {
				ve := new(errors.Validation)
				if stderrors.As(err, &ve) {
					return ve.ValidateName("match-families" + "." + strconv.Itoa(i))
				}
				ce := new(errors.CompositeError)
				if stderrors.As(err, &ce) {
					return ce.ValidateName("match-families" + "." + strconv.Itoa(i))
				}

				return err
			}
		}

	}

	return nil
}

func (m *BgpRoutePolicyStatement) validateMatchNeighbors(formats strfmt.Registry) error {
	if typeutils.IsZero(m.MatchNeighbors) { // not required
		return nil
	}

	if m.MatchNeighbors != nil {
		if err := m.MatchNeighbors.Validate(formats); err != nil {
			ve := new(errors.Validation)
			if stderrors.As(err, &ve) {
				return ve.ValidateName("match-neighbors")
			}
			ce := new(errors.CompositeError)
			if stderrors.As(err, &ce) {
				return ce.ValidateName("match-neighbors")
			}

			return err
		}
	}

	return nil
}

func (m *BgpRoutePolicyStatement) validateMatchPrefixes(formats strfmt.Registry) error {
	if typeutils.IsZero(m.MatchPrefixes) { // not required
		return nil
	}

	if m.MatchPrefixes != nil {
		if err := m.MatchPrefixes.Validate(formats); err != nil {
			ve := new(errors.Validation)
			if stderrors.As(err, &ve) {
				return ve.ValidateName("match-prefixes")
			}
			ce := new(errors.CompositeError)
			if stderrors.As(err, &ce) {
				return ce.ValidateName("match-prefixes")
			}

			return err
		}
	}

	return nil
}

func (m *BgpRoutePolicyStatement) validateNexthop(formats strfmt.Registry) error {
	if typeutils.IsZero(m.Nexthop) { // not required
		return nil
	}

	if m.Nexthop != nil {
		if err := m.Nexthop.Validate(formats); err != nil {
			ve := new(errors.Validation)
			if stderrors.As(err, &ve) {
				return ve.ValidateName("nexthop")
			}
			ce := new(errors.CompositeError)
			if stderrors.As(err, &ce) {
				return ce.ValidateName("nexthop")
			}

			return err
		}
	}

	return nil
}

var bgpRoutePolicyStatementTypeRouteActionPropEnum []any

func init() {
	var res []string
	if err := json.Unmarshal([]byte(`["none","accept","reject"]`), &res); err != nil {
		panic(err)
	}
	for _, v := range res {
		bgpRoutePolicyStatementTypeRouteActionPropEnum = append(bgpRoutePolicyStatementTypeRouteActionPropEnum, v)
	}
}

const (

	// BgpRoutePolicyStatementRouteActionNone captures enum value "none"
	BgpRoutePolicyStatementRouteActionNone string = "none"

	// BgpRoutePolicyStatementRouteActionAccept captures enum value "accept"
	BgpRoutePolicyStatementRouteActionAccept string = "accept"

	// BgpRoutePolicyStatementRouteActionReject captures enum value "reject"
	BgpRoutePolicyStatementRouteActionReject string = "reject"
)

// prop value enum
func (m *BgpRoutePolicyStatement) validateRouteActionEnum(path, location string, value string) error {
	if err := validate.EnumCase(path, location, value, bgpRoutePolicyStatementTypeRouteActionPropEnum, true); err != nil {
		return err
	}
	return nil
}

func (m *BgpRoutePolicyStatement) validateRouteAction(formats strfmt.Registry) error {
	if typeutils.IsZero(m.RouteAction) { // not required
		return nil
	}

	// value enum
	if err := m.validateRouteActionEnum("route-action", "body", m.RouteAction); err != nil {
		return err
	}

	return nil
}

// ContextValidate validate this bgp route policy statement based on the context it is used
func (m *BgpRoutePolicyStatement) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
	var res []error

	if err := m.contextValidateMatchFamilies(ctx, formats); err != nil {
		res = append(res, err)
	}

	if err := m.contextValidateMatchNeighbors(ctx, formats); err != nil {
		res = append(res, err)
	}

	if err := m.contextValidateMatchPrefixes(ctx, formats); err != nil {
		res = append(res, err)
	}

	if err := m.contextValidateNexthop(ctx, formats); err != nil {
		res = append(res, err)
	}

	if len(res) > 0 {
		return errors.CompositeValidationError(res...)
	}
	return nil
}

func (m *BgpRoutePolicyStatement) contextValidateMatchFamilies(ctx context.Context, formats strfmt.Registry) error {

	for i := 0; i < len(m.MatchFamilies); i++ {

		if m.MatchFamilies[i] != nil {

			if typeutils.IsZero(m.MatchFamilies[i]) { // not required
				return nil
			}

			if err := m.MatchFamilies[i].ContextValidate(ctx, formats); err != nil {
				ve := new(errors.Validation)
				if stderrors.As(err, &ve) {
					return ve.ValidateName("match-families" + "." + strconv.Itoa(i))
				}
				ce := new(errors.CompositeError)
				if stderrors.As(err, &ce) {
					return ce.ValidateName("match-families" + "." + strconv.Itoa(i))
				}

				return err
			}
		}

	}

	return nil
}

func (m *BgpRoutePolicyStatement) contextValidateMatchNeighbors(ctx context.Context, formats strfmt.Registry) error {

	if m.MatchNeighbors != nil {

		if typeutils.IsZero(m.MatchNeighbors) { // not required
			return nil
		}

		if err := m.MatchNeighbors.ContextValidate(ctx, formats); err != nil {
			ve := new(errors.Validation)
			if stderrors.As(err, &ve) {
				return ve.ValidateName("match-neighbors")
			}
			ce := new(errors.CompositeError)
			if stderrors.As(err, &ce) {
				return ce.ValidateName("match-neighbors")
			}

			return err
		}
	}

	return nil
}

func (m *BgpRoutePolicyStatement) contextValidateMatchPrefixes(ctx context.Context, formats strfmt.Registry) error {

	if m.MatchPrefixes != nil {

		if typeutils.IsZero(m.MatchPrefixes) { // not required
			return nil
		}

		if err := m.MatchPrefixes.ContextValidate(ctx, formats); err != nil {
			ve := new(errors.Validation)
			if stderrors.As(err, &ve) {
				return ve.ValidateName("match-prefixes")
			}
			ce := new(errors.CompositeError)
			if stderrors.As(err, &ce) {
				return ce.ValidateName("match-prefixes")
			}

			return err
		}
	}

	return nil
}

func (m *BgpRoutePolicyStatement) contextValidateNexthop(ctx context.Context, formats strfmt.Registry) error {

	if m.Nexthop != nil {

		if typeutils.IsZero(m.Nexthop) { // not required
			return nil
		}

		if err := m.Nexthop.ContextValidate(ctx, formats); err != nil {
			ve := new(errors.Validation)
			if stderrors.As(err, &ve) {
				return ve.ValidateName("nexthop")
			}
			ce := new(errors.CompositeError)
			if stderrors.As(err, &ce) {
				return ce.ValidateName("nexthop")
			}

			return err
		}
	}

	return nil
}

// MarshalBinary interface implementation
func (m *BgpRoutePolicyStatement) MarshalBinary() ([]byte, error) {
	if m == nil {
		return nil, nil
	}
	return jsonutils.WriteJSON(m)
}

// UnmarshalBinary interface implementation
func (m *BgpRoutePolicyStatement) UnmarshalBinary(b []byte) error {
	var res BgpRoutePolicyStatement
	if err := jsonutils.ReadJSON(b, &res); err != nil {
		return err
	}
	*m = res
	return nil
}
