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

package models

// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command

import (
	"context"
	"encoding/json"

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

// VolumeGroupAction Performs an action (start stop reset ) on a volume group(one at a time).
//
// Min Properties: 1
// Max Properties: 1
//
// swagger:model VolumeGroupAction
type VolumeGroupAction struct {

	// reset
	Reset *VolumeGroupActionReset `json:"reset,omitempty"`

	// start
	Start *VolumeGroupActionStart `json:"start,omitempty"`

	// stop
	Stop *VolumeGroupActionStop `json:"stop,omitempty"`

	// volume group action additional properties
	VolumeGroupActionAdditionalProperties map[string]interface{} `json:"-"`
}

// UnmarshalJSON unmarshals this object with additional properties from JSON
func (m *VolumeGroupAction) UnmarshalJSON(data []byte) error {
	// stage 1, bind the properties
	var stage1 struct {

		// reset
		Reset *VolumeGroupActionReset `json:"reset,omitempty"`

		// start
		Start *VolumeGroupActionStart `json:"start,omitempty"`

		// stop
		Stop *VolumeGroupActionStop `json:"stop,omitempty"`
	}
	if err := json.Unmarshal(data, &stage1); err != nil {
		return err
	}
	var rcv VolumeGroupAction

	rcv.Reset = stage1.Reset
	rcv.Start = stage1.Start
	rcv.Stop = stage1.Stop
	*m = rcv

	// stage 2, remove properties and add to map
	stage2 := make(map[string]json.RawMessage)
	if err := json.Unmarshal(data, &stage2); err != nil {
		return err
	}

	delete(stage2, "reset")
	delete(stage2, "start")
	delete(stage2, "stop")
	// stage 3, add additional properties values
	if len(stage2) > 0 {
		result := make(map[string]interface{})
		for k, v := range stage2 {
			var toadd interface{}
			if err := json.Unmarshal(v, &toadd); err != nil {
				return err
			}
			result[k] = toadd
		}
		m.VolumeGroupActionAdditionalProperties = result
	}

	return nil
}

// MarshalJSON marshals this object with additional properties into a JSON object
func (m VolumeGroupAction) MarshalJSON() ([]byte, error) {
	var stage1 struct {

		// reset
		Reset *VolumeGroupActionReset `json:"reset,omitempty"`

		// start
		Start *VolumeGroupActionStart `json:"start,omitempty"`

		// stop
		Stop *VolumeGroupActionStop `json:"stop,omitempty"`
	}

	stage1.Reset = m.Reset
	stage1.Start = m.Start
	stage1.Stop = m.Stop

	// make JSON object for known properties
	props, err := json.Marshal(stage1)
	if err != nil {
		return nil, err
	}

	if len(m.VolumeGroupActionAdditionalProperties) == 0 { // no additional properties
		return props, nil
	}

	// make JSON object for the additional properties
	additional, err := json.Marshal(m.VolumeGroupActionAdditionalProperties)
	if err != nil {
		return nil, err
	}

	if len(props) < 3 { // "{}": only additional properties
		return additional, nil
	}

	// concatenate the 2 objects
	return swag.ConcatJSON(props, additional), nil
}

// Validate validates this volume group action
func (m *VolumeGroupAction) Validate(formats strfmt.Registry) error {
	var res []error

	// short circuits minProperties > 0
	if m == nil {
		return errors.TooFewProperties("", "body", 1)
	}

	props := make(map[string]json.RawMessage, 3+10)
	j, err := swag.WriteJSON(m)
	if err != nil {
		return err
	}

	if err = swag.ReadJSON(j, &props); err != nil {
		return err
	}

	nprops := len(props)

	// minProperties: 1
	if nprops < 1 {
		return errors.TooFewProperties("", "body", 1)
	}

	// maxProperties: 1
	if nprops > 1 {
		return errors.TooManyProperties("", "body", 1)
	}

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

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

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

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

func (m *VolumeGroupAction) validateReset(formats strfmt.Registry) error {
	if swag.IsZero(m.Reset) { // not required
		return nil
	}

	if m.Reset != nil {
		if err := m.Reset.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("reset")
			} else if ce, ok := err.(*errors.CompositeError); ok {
				return ce.ValidateName("reset")
			}
			return err
		}
	}

	return nil
}

func (m *VolumeGroupAction) validateStart(formats strfmt.Registry) error {
	if swag.IsZero(m.Start) { // not required
		return nil
	}

	if m.Start != nil {
		if err := m.Start.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("start")
			} else if ce, ok := err.(*errors.CompositeError); ok {
				return ce.ValidateName("start")
			}
			return err
		}
	}

	return nil
}

func (m *VolumeGroupAction) validateStop(formats strfmt.Registry) error {
	if swag.IsZero(m.Stop) { // not required
		return nil
	}

	if m.Stop != nil {
		if err := m.Stop.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("stop")
			} else if ce, ok := err.(*errors.CompositeError); ok {
				return ce.ValidateName("stop")
			}
			return err
		}
	}

	return nil
}

// ContextValidate validate this volume group action based on the context it is used
func (m *VolumeGroupAction) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
	var res []error

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

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

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

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

func (m *VolumeGroupAction) contextValidateReset(ctx context.Context, formats strfmt.Registry) error {

	if m.Reset != nil {

		if swag.IsZero(m.Reset) { // not required
			return nil
		}

		if err := m.Reset.ContextValidate(ctx, formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("reset")
			} else if ce, ok := err.(*errors.CompositeError); ok {
				return ce.ValidateName("reset")
			}
			return err
		}
	}

	return nil
}

func (m *VolumeGroupAction) contextValidateStart(ctx context.Context, formats strfmt.Registry) error {

	if m.Start != nil {

		if swag.IsZero(m.Start) { // not required
			return nil
		}

		if err := m.Start.ContextValidate(ctx, formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("start")
			} else if ce, ok := err.(*errors.CompositeError); ok {
				return ce.ValidateName("start")
			}
			return err
		}
	}

	return nil
}

func (m *VolumeGroupAction) contextValidateStop(ctx context.Context, formats strfmt.Registry) error {

	if m.Stop != nil {

		if swag.IsZero(m.Stop) { // not required
			return nil
		}

		if err := m.Stop.ContextValidate(ctx, formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("stop")
			} else if ce, ok := err.(*errors.CompositeError); ok {
				return ce.ValidateName("stop")
			}
			return err
		}
	}

	return nil
}

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

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