// 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 (
	"encoding/json"

	strfmt "github.com/go-openapi/strfmt"

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

// WritableIPAddress writable IP address
// swagger:model WritableIPAddress
type WritableIPAddress struct {

	// Address
	//
	// IPv4 or IPv6 address (with mask)
	// Required: true
	Address *string `json:"address"`

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

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

	// Description
	// Max Length: 100
	Description string `json:"description,omitempty"`

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

	// Interface
	Interface int64 `json:"interface,omitempty"`

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

	// NAT (Inside)
	//
	// The IP for which this address is the "outside" IP
	NatInside int64 `json:"nat_inside,omitempty"`

	// Role
	//
	// The functional role of this IP
	Role int64 `json:"role,omitempty"`

	// Status
	//
	// The operational status of this IP
	Status int64 `json:"status,omitempty"`

	// Tenant
	Tenant int64 `json:"tenant,omitempty"`

	// VRF
	Vrf int64 `json:"vrf,omitempty"`
}

// Validate validates this writable IP address
func (m *WritableIPAddress) Validate(formats strfmt.Registry) error {
	var res []error

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

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

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

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

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

func (m *WritableIPAddress) validateAddress(formats strfmt.Registry) error {

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

	return nil
}

func (m *WritableIPAddress) validateDescription(formats strfmt.Registry) error {

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

	if err := validate.MaxLength("description", "body", string(m.Description), 100); err != nil {
		return err
	}

	return nil
}

var writableIpAddressTypeRolePropEnum []interface{}

func init() {
	var res []int64
	if err := json.Unmarshal([]byte(`[10,20,30,40,41,42,43,44]`), &res); err != nil {
		panic(err)
	}
	for _, v := range res {
		writableIpAddressTypeRolePropEnum = append(writableIpAddressTypeRolePropEnum, v)
	}
}

// prop value enum
func (m *WritableIPAddress) validateRoleEnum(path, location string, value int64) error {
	if err := validate.Enum(path, location, value, writableIpAddressTypeRolePropEnum); err != nil {
		return err
	}
	return nil
}

func (m *WritableIPAddress) validateRole(formats strfmt.Registry) error {

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

	// value enum
	if err := m.validateRoleEnum("role", "body", m.Role); err != nil {
		return err
	}

	return nil
}

var writableIpAddressTypeStatusPropEnum []interface{}

func init() {
	var res []int64
	if err := json.Unmarshal([]byte(`[1,2,3,5]`), &res); err != nil {
		panic(err)
	}
	for _, v := range res {
		writableIpAddressTypeStatusPropEnum = append(writableIpAddressTypeStatusPropEnum, v)
	}
}

// prop value enum
func (m *WritableIPAddress) validateStatusEnum(path, location string, value int64) error {
	if err := validate.Enum(path, location, value, writableIpAddressTypeStatusPropEnum); err != nil {
		return err
	}
	return nil
}

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

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

	// value enum
	if err := m.validateStatusEnum("status", "body", m.Status); err != nil {
		return err
	}

	return nil
}

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

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