// 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 tenancy

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

import (
	"net/http"
	"time"

	"golang.org/x/net/context"

	"github.com/go-openapi/errors"
	"github.com/go-openapi/runtime"
	cr "github.com/go-openapi/runtime/client"
	"github.com/go-openapi/swag"

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

	"github.com/digitalocean/go-netbox/netbox/models"
)

// NewTenancyTenantGroupsUpdateParams creates a new TenancyTenantGroupsUpdateParams object
// with the default values initialized.
func NewTenancyTenantGroupsUpdateParams() *TenancyTenantGroupsUpdateParams {
	var ()
	return &TenancyTenantGroupsUpdateParams{

		timeout: cr.DefaultTimeout,
	}
}

// NewTenancyTenantGroupsUpdateParamsWithTimeout creates a new TenancyTenantGroupsUpdateParams object
// with the default values initialized, and the ability to set a timeout on a request
func NewTenancyTenantGroupsUpdateParamsWithTimeout(timeout time.Duration) *TenancyTenantGroupsUpdateParams {
	var ()
	return &TenancyTenantGroupsUpdateParams{

		timeout: timeout,
	}
}

// NewTenancyTenantGroupsUpdateParamsWithContext creates a new TenancyTenantGroupsUpdateParams object
// with the default values initialized, and the ability to set a context for a request
func NewTenancyTenantGroupsUpdateParamsWithContext(ctx context.Context) *TenancyTenantGroupsUpdateParams {
	var ()
	return &TenancyTenantGroupsUpdateParams{

		Context: ctx,
	}
}

// NewTenancyTenantGroupsUpdateParamsWithHTTPClient creates a new TenancyTenantGroupsUpdateParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
func NewTenancyTenantGroupsUpdateParamsWithHTTPClient(client *http.Client) *TenancyTenantGroupsUpdateParams {
	var ()
	return &TenancyTenantGroupsUpdateParams{
		HTTPClient: client,
	}
}

/*TenancyTenantGroupsUpdateParams contains all the parameters to send to the API endpoint
for the tenancy tenant groups update operation typically these are written to a http.Request
*/
type TenancyTenantGroupsUpdateParams struct {

	/*Data*/
	Data *models.TenantGroup
	/*ID
	  A unique integer value identifying this tenant group.

	*/
	ID int64

	timeout    time.Duration
	Context    context.Context
	HTTPClient *http.Client
}

// WithTimeout adds the timeout to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) WithTimeout(timeout time.Duration) *TenancyTenantGroupsUpdateParams {
	o.SetTimeout(timeout)
	return o
}

// SetTimeout adds the timeout to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) SetTimeout(timeout time.Duration) {
	o.timeout = timeout
}

// WithContext adds the context to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) WithContext(ctx context.Context) *TenancyTenantGroupsUpdateParams {
	o.SetContext(ctx)
	return o
}

// SetContext adds the context to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) SetContext(ctx context.Context) {
	o.Context = ctx
}

// WithHTTPClient adds the HTTPClient to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) WithHTTPClient(client *http.Client) *TenancyTenantGroupsUpdateParams {
	o.SetHTTPClient(client)
	return o
}

// SetHTTPClient adds the HTTPClient to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) SetHTTPClient(client *http.Client) {
	o.HTTPClient = client
}

// WithData adds the data to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) WithData(data *models.TenantGroup) *TenancyTenantGroupsUpdateParams {
	o.SetData(data)
	return o
}

// SetData adds the data to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) SetData(data *models.TenantGroup) {
	o.Data = data
}

// WithID adds the id to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) WithID(id int64) *TenancyTenantGroupsUpdateParams {
	o.SetID(id)
	return o
}

// SetID adds the id to the tenancy tenant groups update params
func (o *TenancyTenantGroupsUpdateParams) SetID(id int64) {
	o.ID = id
}

// WriteToRequest writes these params to a swagger request
func (o *TenancyTenantGroupsUpdateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {

	if err := r.SetTimeout(o.timeout); err != nil {
		return err
	}
	var res []error

	if o.Data != nil {
		if err := r.SetBodyParam(o.Data); err != nil {
			return err
		}
	}

	// path param id
	if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
		return err
	}

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