package obsws

import (
	"errors"
	"time"
)

// This file is automatically generated.
// https://github.com/christopher-dG/go-obs-websocket/blob/master/codegen/protocol.py

// SetCurrentProfileRequest : Set the currently active profile.
//
// Since obs-websocket version: 4.0.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setcurrentprofile
type SetCurrentProfileRequest struct {
	// Name of the desired profile.
	// Required: Yes.
	ProfileName string `json:"profile-name"`
	_request    `json:",squash"`
	response    chan SetCurrentProfileResponse
}

// NewSetCurrentProfileRequest returns a new SetCurrentProfileRequest.
func NewSetCurrentProfileRequest(profileName string) SetCurrentProfileRequest {
	return SetCurrentProfileRequest{
		profileName,
		_request{
			ID_:   GetMessageID(),
			Type_: "SetCurrentProfile",
			err:   make(chan error, 1),
		},
		make(chan SetCurrentProfileResponse, 1),
	}
}

// Send sends the request.
func (r *SetCurrentProfileRequest) Send(c Client) error {
	if r.sent {
		return ErrAlreadySent
	}
	future, err := c.SendRequest(r)
	if err != nil {
		return err
	}
	r.sent = true
	go func() {
		m := <-future
		var resp SetCurrentProfileResponse
		if err = mapToStruct(m, &resp); err != nil {
			r.err <- err
		} else if resp.Status() != StatusOK {
			r.err <- errors.New(resp.Error())
		} else {
			r.response <- resp
		}
	}()
	return nil
}

// Receive waits for the response.
func (r SetCurrentProfileRequest) Receive() (SetCurrentProfileResponse, error) {
	if !r.sent {
		return SetCurrentProfileResponse{}, ErrNotSent
	}
	if receiveTimeout == 0 {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return SetCurrentProfileResponse{}, err
		}
	} else {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return SetCurrentProfileResponse{}, err
		case <-time.After(receiveTimeout):
			return SetCurrentProfileResponse{}, ErrReceiveTimeout
		}
	}
}

// SendReceive sends the request then immediately waits for the response.
func (r SetCurrentProfileRequest) SendReceive(c Client) (SetCurrentProfileResponse, error) {
	if err := r.Send(c); err != nil {
		return SetCurrentProfileResponse{}, err
	}
	return r.Receive()
}

// SetCurrentProfileResponse : Response for SetCurrentProfileRequest.
//
// Since obs-websocket version: 4.0.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#setcurrentprofile
type SetCurrentProfileResponse struct {
	_response `json:",squash"`
}

// GetCurrentProfileRequest : Get the name of the current profile.
//
// Since obs-websocket version: 4.0.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getcurrentprofile
type GetCurrentProfileRequest struct {
	_request `json:",squash"`
	response chan GetCurrentProfileResponse
}

// NewGetCurrentProfileRequest returns a new GetCurrentProfileRequest.
func NewGetCurrentProfileRequest() GetCurrentProfileRequest {
	return GetCurrentProfileRequest{
		_request{
			ID_:   GetMessageID(),
			Type_: "GetCurrentProfile",
			err:   make(chan error, 1),
		},
		make(chan GetCurrentProfileResponse, 1),
	}
}

// Send sends the request.
func (r *GetCurrentProfileRequest) Send(c Client) error {
	if r.sent {
		return ErrAlreadySent
	}
	future, err := c.SendRequest(r)
	if err != nil {
		return err
	}
	r.sent = true
	go func() {
		m := <-future
		var resp GetCurrentProfileResponse
		if err = mapToStruct(m, &resp); err != nil {
			r.err <- err
		} else if resp.Status() != StatusOK {
			r.err <- errors.New(resp.Error())
		} else {
			r.response <- resp
		}
	}()
	return nil
}

// Receive waits for the response.
func (r GetCurrentProfileRequest) Receive() (GetCurrentProfileResponse, error) {
	if !r.sent {
		return GetCurrentProfileResponse{}, ErrNotSent
	}
	if receiveTimeout == 0 {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return GetCurrentProfileResponse{}, err
		}
	} else {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return GetCurrentProfileResponse{}, err
		case <-time.After(receiveTimeout):
			return GetCurrentProfileResponse{}, ErrReceiveTimeout
		}
	}
}

// SendReceive sends the request then immediately waits for the response.
func (r GetCurrentProfileRequest) SendReceive(c Client) (GetCurrentProfileResponse, error) {
	if err := r.Send(c); err != nil {
		return GetCurrentProfileResponse{}, err
	}
	return r.Receive()
}

// GetCurrentProfileResponse : Response for GetCurrentProfileRequest.
//
// Since obs-websocket version: 4.0.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#getcurrentprofile
type GetCurrentProfileResponse struct {
	// Name of the currently active profile.
	// Required: Yes.
	ProfileName string `json:"profile-name"`
	_response   `json:",squash"`
}

// ListProfilesRequest : Get a list of available profiles.
//
// Since obs-websocket version: 4.0.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#listprofiles
type ListProfilesRequest struct {
	_request `json:",squash"`
	response chan ListProfilesResponse
}

// NewListProfilesRequest returns a new ListProfilesRequest.
func NewListProfilesRequest() ListProfilesRequest {
	return ListProfilesRequest{
		_request{
			ID_:   GetMessageID(),
			Type_: "ListProfiles",
			err:   make(chan error, 1),
		},
		make(chan ListProfilesResponse, 1),
	}
}

// Send sends the request.
func (r *ListProfilesRequest) Send(c Client) error {
	if r.sent {
		return ErrAlreadySent
	}
	future, err := c.SendRequest(r)
	if err != nil {
		return err
	}
	r.sent = true
	go func() {
		m := <-future
		var resp ListProfilesResponse
		if err = mapToStruct(m, &resp); err != nil {
			r.err <- err
		} else if resp.Status() != StatusOK {
			r.err <- errors.New(resp.Error())
		} else {
			r.response <- resp
		}
	}()
	return nil
}

// Receive waits for the response.
func (r ListProfilesRequest) Receive() (ListProfilesResponse, error) {
	if !r.sent {
		return ListProfilesResponse{}, ErrNotSent
	}
	if receiveTimeout == 0 {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return ListProfilesResponse{}, err
		}
	} else {
		select {
		case resp := <-r.response:
			return resp, nil
		case err := <-r.err:
			return ListProfilesResponse{}, err
		case <-time.After(receiveTimeout):
			return ListProfilesResponse{}, ErrReceiveTimeout
		}
	}
}

// SendReceive sends the request then immediately waits for the response.
func (r ListProfilesRequest) SendReceive(c Client) (ListProfilesResponse, error) {
	if err := r.Send(c); err != nil {
		return ListProfilesResponse{}, err
	}
	return r.Receive()
}

// ListProfilesResponse : Response for ListProfilesRequest.
//
// Since obs-websocket version: 4.0.0.
//
// https://github.com/Palakis/obs-websocket/blob/4.x-current/docs/generated/protocol.md#listprofiles
type ListProfilesResponse struct {
	// List of available profiles.
	// Required: Yes.
	Profiles  []map[string]interface{} `json:"profiles"`
	_response `json:",squash"`
}
