package com.lutao.cloud.consume.kafka.consumer;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lutao.cloud.collect.vo.DataAddVO;
import com.lutao.cloud.common.core.util.StringUtil;
import com.lutao.cloud.consume.factory.CommandStrategy;
import com.lutao.cloud.consume.factory.CommandStrategyFactory;
import com.lutao.cloud.consume.service.ConsumerLogService;
import com.lutao.entity.CollectLog;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.kafka.annotation.KafkaHandler;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 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.
 */
@Component
@Slf4j
@KafkaListener(topics = {"oceancrude_static_data_topic"}, groupId = "static-consumer-group")
@AllArgsConstructor
@EnableAspectJAutoProxy
public class StaticConsumer {

    @Resource
    private CommandStrategyFactory commandStrategyFactory;

    @Resource
    private ConsumerLogService collectLogService;

    private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            10,
            15,
            180,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(3),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    /**
     * 接收消息处理
     * SINGLE_MESSAGE 单条消息类型
     * ROLE_GROUP_MESSAGE 根据角色处理消息
     *
     * @param message
     */
    @KafkaHandler
    public void receive(String message) {
        if (StringUtil.isNotBlank(message)) {


            try {
                DataAddVO dataAddVO = convertMessageToEntity(message);

                //需要操作的数据表
                String resource = dataAddVO.getResource();

                //date里面的数据
                JsonNode jsonDate = dataAddVO.getJsonDate();
                //得到命令
                String command = dataAddVO.getCommand();

                if (StringUtil.isBlank(command)) {
                    return;
                }

                CommandStrategy<Object> strategy = commandStrategyFactory.createStrategy(resource);
                //数据库不同，策略不同
                strategy.execute(command, jsonDate, dataAddVO);

            } catch (Exception e) {
                log.error("static-consumer receive message error:{}", e);
                CollectLog collectLog = new CollectLog();
                collectLog.setCommand("error");
                collectLog.setData(e.getMessage() + "===" + message);
                collectLogService.save(collectLog);
                e.printStackTrace();
            }

        }
    }


    /**
     * 将消息转换为实体
     *
     * @param message 消息
     */
    public DataAddVO convertMessageToEntity(String message) {
        try {
            //创建ObjectMapper对象
            ObjectMapper objectMapper = new ObjectMapper();
            //将字符串转换为JSON对象
            JsonNode jsonNode = objectMapper.readTree(message);
            //将JSON对象转换为Java对象
            return objectMapper.treeToValue(jsonNode, DataAddVO.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }


}
