// Custom error implementation to make our errors being served with appropriate status codes

package report

import (
	"github.com/stvp/rollbar"
)

const (
	BAD_REQUEST = "bad_request"
	NOT_FOUND   = "not_found"
)

// Custom error struct to hold error message, and error type
type CustomError struct {
	Type    string
	Message string
}

// Custom error struct to hold error message, stack trace, and error level
type CustomAlert struct {
	message string
	level   string
	trace   rollbar.Stack
}

// Implementation of error interface
func (err *CustomError) Error() string {
	return err.Message
}

// Handy function for error type bad request
func NewBadRequestCustomError(message string) *CustomError {
	return NewCustomError(BAD_REQUEST, message)
}

// Handy function for error type not found
func NewNotFoundCustomError(message string) *CustomError {
	return NewCustomError(NOT_FOUND, message)
}

// Handy function for custom error without error type
func NewDefaultCustomError(message string) *CustomError {
	return NewCustomError("", message)
}

// Main function to instantiate custom error struct
func NewCustomError(err_type string, message string) *CustomError {
	return &CustomError{
		Message: message,
		Type:    err_type,
	}
}

// Implementation of error interface
func (e *CustomAlert) Error() string {
	return e.message
}

// Handy function for alert type: Error
func NewErrorAlert(message string) *CustomAlert {
	return NewCustomAlert(rollbar.ERR, message)
}

// Handy function for alert type: Warning
func NewWarningAlert(message string) *CustomAlert {
	return NewCustomAlert(rollbar.WARN, message)
}

// Handy function for alert type: Debug
func NewDebugAlert(message string) *CustomAlert {
	return NewCustomAlert(rollbar.DEBUG, message)
}

// Handy function for alert type: Info
func NewInfoAlert(message string) *CustomAlert {
	return NewCustomAlert(rollbar.INFO, message)
}

// Handy function for alert type: Critical
func NewCriticalAlert(message string) *CustomAlert {
	return NewCustomAlert(rollbar.CRIT, message)
}

// Main function to instantiate custom alert struct
func NewCustomAlert(level string, message string) *CustomAlert {
	trace := rollbar.BuildStack(3) // 3 = skip 3 useless traces from top which build this alert

	return &CustomAlert{
		level:   level,
		message: message,
		trace:   trace,
	}
}

// Returns rollbar field to store additional details to send to rollbar
func NewField(name string, data interface{}) *rollbar.Field {
	return &rollbar.Field{
		Name: name,
		Data: data,
	}
}
