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

// Copyright 2018 The go-netbox Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

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 (
	strfmt "github.com/go-openapi/strfmt"

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

// Device device
// swagger:model Device
type Device struct {

	// Asset tag
	//
	// A unique tag used to identify this device
	// Max Length: 50
	AssetTag string `json:"asset_tag,omitempty"`

	// cluster
	// Required: true
	Cluster *NestedCluster `json:"cluster"`

	// Comments
	Comments string `json:"comments,omitempty"`

	// Created
	// Read Only: true
	Created strfmt.Date `json:"created,omitempty"`

	// Custom fields
	CustomFields interface{} `json:"custom_fields,omitempty"`

	// device role
	// Required: true
	DeviceRole *NestedDeviceRole `json:"device_role"`

	// device type
	// Required: true
	DeviceType *NestedDeviceType `json:"device_type"`

	// Display name
	// Read Only: true
	DisplayName string `json:"display_name,omitempty"`

	// face
	// Required: true
	Face *DeviceFace `json:"face"`

	// ID
	// Read Only: true
	ID int64 `json:"id,omitempty"`

	// Last updated
	// Read Only: true
	LastUpdated strfmt.DateTime `json:"last_updated,omitempty"`

	// Name
	// Max Length: 64
	Name string `json:"name,omitempty"`

	// Parent device
	// Read Only: true
	ParentDevice string `json:"parent_device,omitempty"`

	// platform
	// Required: true
	Platform *NestedPlatform `json:"platform"`

	// Position (U)
	//
	// The lowest-numbered unit occupied by the device
	// Required: true
	// Maximum: 32767
	// Minimum: 1
	Position *int64 `json:"position"`

	// primary ip
	// Required: true
	PrimaryIP *DeviceIPAddress `json:"primary_ip"`

	// primary ip4
	// Required: true
	PrimaryIp4 *DeviceIPAddress `json:"primary_ip4"`

	// primary ip6
	// Required: true
	PrimaryIp6 *DeviceIPAddress `json:"primary_ip6"`

	// rack
	// Required: true
	Rack *NestedRack `json:"rack"`

	// Serial number
	// Max Length: 50
	Serial string `json:"serial,omitempty"`

	// site
	// Required: true
	Site *NestedSite `json:"site"`

	// status
	// Required: true
	Status *DeviceStatus `json:"status"`

	// tenant
	// Required: true
	Tenant *NestedTenant `json:"tenant"`

	// Vc position
	// Required: true
	// Maximum: 255
	// Minimum: 0
	VcPosition *int64 `json:"vc_position"`

	// Vc priority
	// Maximum: 255
	// Minimum: 0
	VcPriority *int64 `json:"vc_priority,omitempty"`

	// virtual chassis
	// Required: true
	VirtualChassis *DeviceVirtualChassis `json:"virtual_chassis"`
}

// Validate validates this device
func (m *Device) Validate(formats strfmt.Registry) error {
	var res []error

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

func (m *Device) validateAssetTag(formats strfmt.Registry) error {

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

	if err := validate.MaxLength("asset_tag", "body", string(m.AssetTag), 50); err != nil {
		return err
	}

	return nil
}

func (m *Device) validateCluster(formats strfmt.Registry) error {

	if err := validate.Required("cluster", "body", m.Cluster); err != nil {
		return err
	}

	if m.Cluster != nil {

		if err := m.Cluster.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("cluster")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateDeviceRole(formats strfmt.Registry) error {

	if err := validate.Required("device_role", "body", m.DeviceRole); err != nil {
		return err
	}

	if m.DeviceRole != nil {

		if err := m.DeviceRole.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("device_role")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateDeviceType(formats strfmt.Registry) error {

	if err := validate.Required("device_type", "body", m.DeviceType); err != nil {
		return err
	}

	if m.DeviceType != nil {

		if err := m.DeviceType.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("device_type")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateFace(formats strfmt.Registry) error {

	if err := validate.Required("face", "body", m.Face); err != nil {
		return err
	}

	if m.Face != nil {

		if err := m.Face.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("face")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateName(formats strfmt.Registry) error {

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

	if err := validate.MaxLength("name", "body", string(m.Name), 64); err != nil {
		return err
	}

	return nil
}

func (m *Device) validatePlatform(formats strfmt.Registry) error {

	if err := validate.Required("platform", "body", m.Platform); err != nil {
		return err
	}

	if m.Platform != nil {

		if err := m.Platform.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("platform")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validatePosition(formats strfmt.Registry) error {

	if err := validate.Required("position", "body", m.Position); err != nil {
		return err
	}

	if err := validate.MinimumInt("position", "body", int64(*m.Position), 1, false); err != nil {
		return err
	}

	if err := validate.MaximumInt("position", "body", int64(*m.Position), 32767, false); err != nil {
		return err
	}

	return nil
}

func (m *Device) validatePrimaryIP(formats strfmt.Registry) error {

	if err := validate.Required("primary_ip", "body", m.PrimaryIP); err != nil {
		return err
	}

	if m.PrimaryIP != nil {

		if err := m.PrimaryIP.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("primary_ip")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validatePrimaryIp4(formats strfmt.Registry) error {

	if err := validate.Required("primary_ip4", "body", m.PrimaryIp4); err != nil {
		return err
	}

	if m.PrimaryIp4 != nil {

		if err := m.PrimaryIp4.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("primary_ip4")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validatePrimaryIp6(formats strfmt.Registry) error {

	if err := validate.Required("primary_ip6", "body", m.PrimaryIp6); err != nil {
		return err
	}

	if m.PrimaryIp6 != nil {

		if err := m.PrimaryIp6.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("primary_ip6")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateRack(formats strfmt.Registry) error {

	if err := validate.Required("rack", "body", m.Rack); err != nil {
		return err
	}

	if m.Rack != nil {

		if err := m.Rack.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("rack")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateSerial(formats strfmt.Registry) error {

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

	if err := validate.MaxLength("serial", "body", string(m.Serial), 50); err != nil {
		return err
	}

	return nil
}

func (m *Device) validateSite(formats strfmt.Registry) error {

	if err := validate.Required("site", "body", m.Site); err != nil {
		return err
	}

	if m.Site != nil {

		if err := m.Site.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("site")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateStatus(formats strfmt.Registry) error {

	if err := validate.Required("status", "body", m.Status); err != nil {
		return err
	}

	if m.Status != nil {

		if err := m.Status.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("status")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateTenant(formats strfmt.Registry) error {

	if err := validate.Required("tenant", "body", m.Tenant); err != nil {
		return err
	}

	if m.Tenant != nil {

		if err := m.Tenant.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("tenant")
			}
			return err
		}
	}

	return nil
}

func (m *Device) validateVcPosition(formats strfmt.Registry) error {

	if err := validate.Required("vc_position", "body", m.VcPosition); err != nil {
		return err
	}

	if err := validate.MinimumInt("vc_position", "body", int64(*m.VcPosition), 0, false); err != nil {
		return err
	}

	if err := validate.MaximumInt("vc_position", "body", int64(*m.VcPosition), 255, false); err != nil {
		return err
	}

	return nil
}

func (m *Device) validateVcPriority(formats strfmt.Registry) error {

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

	if err := validate.MinimumInt("vc_priority", "body", int64(*m.VcPriority), 0, false); err != nil {
		return err
	}

	if err := validate.MaximumInt("vc_priority", "body", int64(*m.VcPriority), 255, false); err != nil {
		return err
	}

	return nil
}

func (m *Device) validateVirtualChassis(formats strfmt.Registry) error {

	if err := validate.Required("virtual_chassis", "body", m.VirtualChassis); err != nil {
		return err
	}

	if m.VirtualChassis != nil {

		if err := m.VirtualChassis.Validate(formats); err != nil {
			if ve, ok := err.(*errors.Validation); ok {
				return ve.ValidateName("virtual_chassis")
			}
			return err
		}
	}

	return nil
}

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

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