/*
 * Copyright (c) 2018 - present.  Boling Consulting Solutions (bcsw.net)
 *
 * 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.
 */
/*
 * NOTE: This file was generated, manual edits will be overwritten!
 *
 * Generated by 'goCodeGenerator.py':
 *              https://github.com/cboling/OMCI-parser/README.md
 */
package generated

import (
	"errors"
	"fmt"
)

// Custom Go Error messages for common OMCI errors
//
// Response Status code related errors
type OmciErrors interface {
	Error() string
	StatusCode() Results
	GetError() error
}

type OmciError struct {
	err        string
	statusCode Results
}

func (e *OmciError) GetError() error {
	return errors.New(e.err)
}

func (e *OmciError) Error() string {
	return e.err
}

func (e *OmciError) StatusCode() Results {
	return e.statusCode
}

func NewOmciError(text string, status Results) OmciErrors {
	if status == Success {
		panic("Do not use OmciError to convey successful results")
	}
	return &OmciError{
		err:        text,
		statusCode: status,
	}
}

type OmciNonStatusError struct {
	OmciError
}

// NewNonStatusError is for processing errors that do not involve
// frame processing status & results
func NewNonStatusError(args ...interface{}) OmciErrors {
	defaultValue := "command processing error"
	return &OmciProcessingError{
		OmciError: OmciError{
			err: genMessage(defaultValue, args...),
		},
	}
}

type OmciProcessingError struct {
	OmciError
}

// NewProcessingError means the command processing failed at the ONU
// for reasons not described by one of the more specific error codes.
func NewProcessingError(args ...interface{}) OmciErrors {
	defaultValue := "command processing error"
	return &OmciProcessingError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: ProcessingError,
		},
	}
}

type NotSupportedError struct {
	OmciError
}

// NewNotSupportedError means that the message type indicated in byte 3 is
// not supported by the ONU.
func NewNotSupportedError(args ...interface{}) OmciErrors {
	defaultValue := "command not supported"
	return &NotSupportedError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: NotSupported,
		},
	}
}

type ParamError struct {
	OmciError
	FailureMask uint16
}

// NewParameterError means that the command message received by the
// ONU was errored. It would be appropriate if an attribute mask
// were out of range, for example. In practice, this result code is
// frequently used interchangeably with code 1001. However, the
// optional attribute and attribute execution masks in the reply
// messages are only defined for code 1001.
func NewParameterError(mask uint16, args ...interface{}) OmciErrors {
	defaultValue := "parameter error"
	return &ParamError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: ParameterError,
		},
		FailureMask: mask,
	}
}

type UnknownEntityError struct {
	OmciError
}

// NewUnknownEntityError This result means that the managed entity class
// (bytes 5..6) is not supported by the ONU.
func NewUnknownEntityError(args ...interface{}) OmciErrors {
	defaultValue := "unknown managed entity"
	return &UnknownEntityError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: UnknownEntity,
		},
	}
}

type UnknownInstanceError struct {
	OmciError
}

// NewUnknownInstanceError means that the managed entity instance (bytes 7..8)
// does not exist in the ONU.
func NewUnknownInstanceError(args ...interface{}) OmciErrors {
	defaultValue := "unknown managed entity instance"
	return &UnknownInstanceError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: UnknownInstance,
		},
	}
}

type DeviceBusyError struct {
	OmciError
}

// NewDeviceBusyError means that the command could not be processed due
// to process-related congestion at the ONU. This result code may
// also be used as a pause indication to the OLT while the ONU
// conducts a time-consuming operation such as storage of a
// software image into non-volatile memory.
func NewDeviceBusyError(args ...interface{}) OmciErrors {
	defaultValue := "device busy"
	return &DeviceBusyError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: DeviceBusy,
		},
	}
}

type InstanceExistsError struct {
	OmciError
}

// NewInstanceExistsError
func NewInstanceExistsError(args ...interface{}) OmciErrors {
	defaultValue := "instance exists"
	return &InstanceExistsError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: InstanceExists,
		},
	}
}

type AttributeFailureError struct {
	OmciError
}

// NewAttributeFailureError means that the ONU already has a managed entity
// instance that corresponds to the one the OLT is attempting to create.
func NewAttributeFailureError(args ...interface{}) OmciErrors {
	defaultValue := "attribute(s) failed or unknown"
	return &AttributeFailureError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: AttributeFailure,
		},
	}
}

type MessageTruncatedError struct {
	OmciError
}

// NewAttributeFailureError means that the ONU already has a managed entity
// instance that corresponds to the one the OLT is attempting to create.
func NewMessageTruncatedError(args ...interface{}) OmciErrors {
	defaultValue := "out-of-space. Cannot fit attribute into message"
	return &MessageTruncatedError{
		OmciError: OmciError{
			err:        genMessage(defaultValue, args...),
			statusCode: ProcessingError,
		},
	}
}

func genMessage(defaultValue string, args ...interface{}) string {
	switch len(args) {
	case 0:
		return defaultValue

	case 1:
		switch first := args[0].(type) {
		case string:
			// Assume a simple, pre-formatted string
			return args[0].(string)

		case func() string:
			// Assume a closure with no other arguments used
			return first()

		default:
			panic("Unsupported parameter type")
		}
	}
	return fmt.Sprintf(args[0].(string), args[1:]...)
}
