/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 rocketmq

/*
#include <rocketmq/CCommon.h>
*/
import "C"
import "fmt"

type rmqError int

//This is error messages
const (
	NIL                        = rmqError(C.OK)
	ErrNullPoint               = rmqError(C.NULL_POINTER)
	ErrMallocFailed            = rmqError(C.MALLOC_FAILED)
	ErrProducerStartFailed     = rmqError(C.PRODUCER_START_FAILED)
	ErrSendSyncFailed          = rmqError(C.PRODUCER_SEND_SYNC_FAILED)
	ErrSendOnewayFailed        = rmqError(C.PRODUCER_SEND_ONEWAY_FAILED)
	ErrSendOrderlyFailed       = rmqError(C.PRODUCER_SEND_ORDERLY_FAILED)
	ErrSendTransactionFailed   = rmqError(C.PRODUCER_SEND_TRANSACTION_FAILED)
	ErrPushConsumerStartFailed = rmqError(C.PUSHCONSUMER_START_FAILED)
	ErrPullConsumerStartFailed = rmqError(C.PULLCONSUMER_START_FAILED)
	ErrFetchMQFailed           = rmqError(C.PULLCONSUMER_FETCH_MQ_FAILED)
	ErrFetchMessageFailed      = rmqError(C.PULLCONSUMER_FETCH_MESSAGE_FAILED)
	ErrNotSupportNow           = rmqError(C.NOT_SUPPORT_NOW)
)

func (e rmqError) Error() string {
	switch e {
	case ErrNullPoint:
		return "null point"
	case ErrMallocFailed:
		return "malloc memory failed"
	case ErrProducerStartFailed:
		return "start producer failed"
	case ErrSendSyncFailed:
		return "send message with sync failed"
	case ErrSendOrderlyFailed:
		return "send message with orderly failed"
	case ErrSendOnewayFailed:
		return "send message with oneway failed"
	case ErrSendTransactionFailed:
		return "send transaction message failed"
	case ErrPushConsumerStartFailed:
		return "start push-consumer failed"
	case ErrPullConsumerStartFailed:
		return "start pull-consumer failed"
	case ErrFetchMQFailed:
		return "fetch MessageQueue failed"
	case ErrFetchMessageFailed:
		return "fetch Message failed"
	case ErrNotSupportNow:
		return "this function is not support"
	default:
		return fmt.Sprintf("unknow error: %v", int(e))
	}
}
