/**
* Copyright (C) 2013 kangliqiang ,kangliq@163.com
*
* 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.
*/
#include "ConsumeMessageConcurrentlyService.h"

#include "DefaultMQPushConsumerImpl.h"
#include "MessageListener.h"
#include "MessageQueue.h"
#include "RebalanceImpl.h"
#include "DefaultMQPushConsumer.h"
#include "MixAll.h"
#include "KPRUtil.h"
#include "UtilAll.h"
#include "OffsetStore.h"

namespace rmq
{


class SubmitConsumeRequestLater : public kpr::TimerHandler
{
public:
    SubmitConsumeRequestLater(std::list<MessageExt*>& msgs,
                              ProcessQueue* pProcessQueue,
                              MessageQueue messageQueue,
                              ConsumeMessageConcurrentlyService* pService)
        : m_msgs(msgs),
          m_pProcessQueue(pProcessQueue),
          m_messageQueue(messageQueue),
          m_pService(pService)
    {

    }

    void OnTimeOut(unsigned int timerID)
    {
    	try
    	{
        	m_pService->submitConsumeRequest(m_msgs, m_pProcessQueue, m_messageQueue, true);
        }
        catch(...)
        {
        	RMQ_ERROR("SubmitConsumeRequestLater OnTimeOut exception");
        }

        delete this;
    }

private:
    std::list<MessageExt*> m_msgs;
    ProcessQueue* m_pProcessQueue;
    MessageQueue m_messageQueue;
    ConsumeMessageConcurrentlyService* m_pService;
};


class CleanExpireMsgTask : public kpr::TimerHandler
{
public:
    CleanExpireMsgTask(ConsumeMessageConcurrentlyService* pService)
        : m_pService(pService)
    {

    }

    void OnTimeOut(unsigned int timerID)
    {
    	try
    	{
        	m_pService->cleanExpireMsg();
        }
        catch(...)
        {
        	RMQ_ERROR("CleanExpireMsgTask OnTimeOut exception");
        }
    }

private:
    ConsumeMessageConcurrentlyService* m_pService;
};



ConsumeMessageConcurrentlyService::ConsumeMessageConcurrentlyService(
    DefaultMQPushConsumerImpl* pDefaultMQPushConsumerImpl,
    MessageListenerConcurrently* pMessageListener)
{
    m_pDefaultMQPushConsumerImpl = pDefaultMQPushConsumerImpl;
    m_pMessageListener = pMessageListener;
    m_pDefaultMQPushConsumer = m_pDefaultMQPushConsumerImpl->getDefaultMQPushConsumer();
    m_consumerGroup = m_pDefaultMQPushConsumer->getConsumerGroup();
    m_pConsumeExecutor = new kpr::ThreadPool("ConsumeMessageThreadPool", 5,
    m_pDefaultMQPushConsumer->getConsumeThreadMin(), m_pDefaultMQPushConsumer->getConsumeThreadMax());
    m_pScheduledExecutorService = new kpr::TimerThread("ConsumeMessageConcurrentlyService", 1000);
    m_pCleanExpireMsgExecutors = new kpr::TimerThread("CleanExpireMsgService", 1000);
	m_pCleanExpireMsgTask = new CleanExpireMsgTask(this);
}

ConsumeMessageConcurrentlyService::~ConsumeMessageConcurrentlyService()
{
	delete m_pCleanExpireMsgTask;
}


void ConsumeMessageConcurrentlyService::start()
{
	m_pCleanExpireMsgExecutors->RegisterTimer(60 * 1000, 60 * 1000, m_pCleanExpireMsgTask, true);
    m_pScheduledExecutorService->Start();
    m_pCleanExpireMsgExecutors->Start();
}

void ConsumeMessageConcurrentlyService::shutdown()
{
    m_pConsumeExecutor->Destroy();
    m_pScheduledExecutorService->Stop();
    m_pScheduledExecutorService->Join();

    m_pCleanExpireMsgExecutors->Stop();
    m_pCleanExpireMsgExecutors->Join();
}


void ConsumeMessageConcurrentlyService::cleanExpireMsg()
{
	kpr::ScopedRLock<kpr::RWMutex> lock(m_pDefaultMQPushConsumerImpl->getRebalanceImpl()->getProcessQueueTableLock());
	std::map<MessageQueue, ProcessQueue*>& processQueueTable
		= m_pDefaultMQPushConsumerImpl->getRebalanceImpl()->getProcessQueueTable();
	RMQ_FOR_EACH(processQueueTable, it)
	{
		ProcessQueue* pq = it->second;
		if (!pq->isDropped())
		{
        	pq->cleanExpiredMsg(m_pDefaultMQPushConsumer);
        }
	}
}


ConsumerStat& ConsumeMessageConcurrentlyService::getConsumerStat()
{
    return m_pDefaultMQPushConsumerImpl->getConsumerStatManager()->getConsumertat();
}

bool ConsumeMessageConcurrentlyService::sendMessageBack(MessageExt& msg,
        ConsumeConcurrentlyContext& context)
{
    try
    {
        m_pDefaultMQPushConsumerImpl->sendMessageBack(msg,
        	context.delayLevelWhenNextConsume, context.messageQueue.getBrokerName());
        return true;
    }
    catch (...)
    {
		RMQ_ERROR("sendMessageBack exception, group: %s, msg: %s",
			m_consumerGroup.c_str(), msg.toString().c_str());
    }

    return false;
}

void ConsumeMessageConcurrentlyService::submitConsumeRequestLater(std::list<MessageExt*>& msgs,
        ProcessQueue* pProcessQueue,
        const MessageQueue& messageQueue)
{
    SubmitConsumeRequestLater* sc = new SubmitConsumeRequestLater(msgs, pProcessQueue, messageQueue, this);
    m_pScheduledExecutorService->RegisterTimer(0, 5000, sc, false);
}

void ConsumeMessageConcurrentlyService::submitConsumeRequest(std::list<MessageExt*>& msgs,
        ProcessQueue* pProcessQueue,
        const MessageQueue& messageQueue,
        bool dispathToConsume)
{
	size_t consumeBatchSize = m_pDefaultMQPushConsumer->getConsumeMessageBatchMaxSize();

	RMQ_DEBUG("submitConsumeRequest begin, msgs.size=%d, messageQueue=%s, consumeBatchSize=%d, dispathToConsume=%d",
		(int)msgs.size(), messageQueue.toString().c_str(), (int)consumeBatchSize, dispathToConsume
    );

    if (msgs.size() <= consumeBatchSize)
    {
        kpr::ThreadPoolWorkPtr consumeRequest = new ConsumeConcurrentlyRequest(msgs, pProcessQueue, messageQueue, this);
        m_pConsumeExecutor->AddWork(consumeRequest);
    }
    else
    {
        std::list<MessageExt*>::iterator it = msgs.begin();
        for (; it != msgs.end();)
        {
            std::list<MessageExt*> msgThis;
            for (size_t i = 0; i < consumeBatchSize; i++, it++)
            {
                if (it != msgs.end())
                {
                    msgThis.push_back(*it);
                }
                else
                {
                    break;
                }
            }

            kpr::ThreadPoolWorkPtr consumeRequest = new ConsumeConcurrentlyRequest(msgThis, pProcessQueue, messageQueue, this);
            m_pConsumeExecutor->AddWork(consumeRequest);
        }
    }

    RMQ_DEBUG("submitConsumeRequest end");
}

void ConsumeMessageConcurrentlyService::updateCorePoolSize(int corePoolSize)
{
	//todo
}

void ConsumeMessageConcurrentlyService::processConsumeResult(ConsumeConcurrentlyStatus status,
        ConsumeConcurrentlyContext& context,
        ConsumeConcurrentlyRequest& consumeRequest)
{
    int ackIndex = context.ackIndex;

    if (consumeRequest.getMsgs().empty())
    {
        return;
    }

    int msgsSize = consumeRequest.getMsgs().size();

    switch (status)
    {
        case CONSUME_SUCCESS:
        {
            if (ackIndex >= msgsSize)
            {
                ackIndex = msgsSize - 1;
            }

            int ok = ackIndex + 1;
            int failed = msgsSize - ok;
            getConsumerStat().consumeMsgOKTotal.fetchAndAdd(ok);
            getConsumerStat().consumeMsgFailedTotal.fetchAndAdd(failed);
        }

        break;
        case RECONSUME_LATER:
            ackIndex = -1;
            getConsumerStat().consumeMsgFailedTotal.fetchAndAdd(msgsSize);
            break;
        default:
            break;
    }

    std::list<MessageExt*>& msgs = consumeRequest.getMsgs();
    std::list<MessageExt*>::iterator it = msgs.begin();

    for (int i = 0; i < ackIndex + 1 && it != msgs.end(); i++)
    {
        it++;
    }

    switch (m_pDefaultMQPushConsumer->getMessageModel())
    {
        case BROADCASTING:
            for (; it != msgs.end(); it++)
            {
                MessageExt* msg = *it;
                RMQ_WARN("BROADCASTING, the message consume failed, drop it, %s", msg->toString().c_str());
            }
            break;
        case CLUSTERING:
        {
            std::list<MessageExt*> msgBackFailed;
            for (; it != msgs.end(); it++)
            {
                MessageExt* msg = *it;
                bool result = sendMessageBack(*msg, context);
                if (!result)
                {
                    msg->setReconsumeTimes(msg->getReconsumeTimes() + 1);
                    msgBackFailed.push_back(msg);
                }
            }

            if (!msgBackFailed.empty())
            {
                it = msgs.begin();

                for (; it != msgs.end();)
                {
                    bool find = false;
                    std::list<MessageExt*>::iterator itFailed = msgBackFailed.begin();
                    for (; itFailed != msgBackFailed.end(); itFailed++)
                    {
                        if (*it == *itFailed)
                        {
                            it = msgs.erase(it);
                            find = true;
                            break;
                        }
                    }

                    if (!find)
                    {
                        it++;
                    }
                }

                submitConsumeRequestLater(msgBackFailed, consumeRequest.getProcessQueue(),
                                          consumeRequest.getMessageQueue());
            }
        }
        break;
        default:
            break;
    }

    long long offset = consumeRequest.getProcessQueue()->removeMessage(consumeRequest.getMsgs());
    if (offset >= 0 && !(consumeRequest.getProcessQueue()->isDropped()))
    {
        m_pDefaultMQPushConsumerImpl->getOffsetStore()->updateOffset(consumeRequest.getMessageQueue(),
                offset, true);
    }
}

std::string& ConsumeMessageConcurrentlyService::getConsumerGroup()
{
    return m_consumerGroup;
}

MessageListenerConcurrently* ConsumeMessageConcurrentlyService::getMessageListener()
{
    return m_pMessageListener;
}

DefaultMQPushConsumerImpl* ConsumeMessageConcurrentlyService::getDefaultMQPushConsumerImpl()
{
    return m_pDefaultMQPushConsumerImpl;
}

ConsumeConcurrentlyRequest::ConsumeConcurrentlyRequest(std::list<MessageExt*>& msgs,
        ProcessQueue* pProcessQueue,
        const MessageQueue& messageQueue,
        ConsumeMessageConcurrentlyService* pService)
{
	m_msgs = msgs;
	m_pProcessQueue = pProcessQueue;
	m_pService = pService;
    m_messageQueue = messageQueue;
}

ConsumeConcurrentlyRequest::~ConsumeConcurrentlyRequest()
{
	m_msgs.clear();
}

void ConsumeConcurrentlyRequest::Do()
{
	RMQ_DEBUG("consumeMessage begin, m_msgs.size=%d", (int)m_msgs.size());

    if (m_pProcessQueue->isDropped())
    {
        RMQ_WARN("the message queue not be able to consume, because it's droped, {%s}",
        	m_messageQueue.toString().c_str());
        return;
    }

	try
	{
	    MessageListenerConcurrently* listener = m_pService->getMessageListener();
	    ConsumeConcurrentlyContext context(m_messageQueue);
	    ConsumeConcurrentlyStatus status = RECONSUME_LATER;

	    ConsumeMessageContext consumeMessageContext;
	    if (m_pService->getDefaultMQPushConsumerImpl()->hasHook())
	    {
	        consumeMessageContext.consumerGroup = m_pService->getConsumerGroup();
	        consumeMessageContext.mq = m_messageQueue;
	        consumeMessageContext.msgList = m_msgs;
	        consumeMessageContext.success = false;
	        m_pService->getDefaultMQPushConsumerImpl()->executeHookBefore(consumeMessageContext);
	    }

	    long long beginTimestamp = KPRUtil::GetCurrentTimeMillis();
	    try
	    {
	        resetRetryTopic(m_msgs);
	        if (!m_msgs.empty())
	        {
	        	std::list<MessageExt*>::iterator it = m_msgs.begin();
			    for (; it != m_msgs.end(); it++)
			    {
			        MessageExt* msg = (*it);
			        msg->putProperty(Message::PROPERTY_CONSUME_START_TIMESTAMP,
			        	UtilAll::toString(KPRUtil::GetCurrentTimeMillis()));
			    }
            }
	        status = listener->consumeMessage(m_msgs, context);
	    }
	    catch (...)
	    {
	        RMQ_WARN("consumeMessage exception, Group: {%s} Msgs: {%d} MQ: {%s}",
	        	m_pService->getConsumerGroup().c_str(),
	        	(int)m_msgs.size(),
	        	m_messageQueue.toString().c_str()
	        );
	    }

	    long long consumeRT = KPRUtil::GetCurrentTimeMillis() - beginTimestamp;

	    if (m_pService->getDefaultMQPushConsumerImpl()->hasHook())
	    {
	        consumeMessageContext.success = (status == CONSUME_SUCCESS);
	        m_pService->getDefaultMQPushConsumerImpl()->executeHookAfter(consumeMessageContext);
	    }

	    m_pService->getConsumerStat().consumeMsgRTTotal.fetchAndAdd(consumeRT);
	    bool updated = MixAll::compareAndIncreaseOnly(m_pService->getConsumerStat().consumeMsgRTMax, consumeRT);
	    if (updated)
	    {
	        RMQ_WARN("consumeMessage RT new max: %lld, Group: %s, Msgs: %d, MQ: %s",
	        	consumeRT,
	        	m_pService->getConsumerGroup().c_str(),
	        	(int)m_msgs.size(),
	        	m_messageQueue.toString().c_str()
	        );
	    }

		if (!m_pProcessQueue->isDropped())
		{
	    	m_pService->processConsumeResult(status, context, *this);
	    }
	    else
	    {
	    	RMQ_WARN("processQueue is dropped without process consume result, messageQueue={%s}, msgs.size={%d}",
	        	m_messageQueue.toString().c_str(), (int)m_msgs.size());
	    }
	}
	catch(...)
	{
		RMQ_WARN("ConsumeConcurrentlyRequest exception");
	}
	RMQ_DEBUG("consumeMessage end, m_msgs.size=%d", (int)m_msgs.size());

    return;
}

void ConsumeConcurrentlyRequest::resetRetryTopic(std::list<MessageExt*>& msgs)
{
    std::string groupTopic = MixAll::getRetryTopic(m_pService->getConsumerGroup());
    std::list<MessageExt*>::iterator it = msgs.begin();

    for (; it != msgs.end(); it++)
    {
        MessageExt* msg = (*it);
        std::string retryTopic = msg->getProperty(Message::PROPERTY_RETRY_TOPIC);
        if (!retryTopic.empty() && groupTopic == msg->getTopic())
        {
            msg->setTopic(retryTopic);
        }
    }
}

}
