/*
 * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & dreamlu.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.
 */

package com.hw.mqtt.service.impl;

import com.hw.mqtt.enums.RedisKeys;
import com.hw.mqtt.service.IMqttBrokerService;
import net.dreamlu.iot.mqtt.spring.server.MqttServerTemplate;
import net.dreamlu.mica.core.utils.StringPool;
import net.dreamlu.mica.redis.cache.MicaRedisCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * mqtt broker 服务
 *
 * @author L.cm
 */
@Service
public class MqttBrokerServiceImpl implements IMqttBrokerService {
  private static final Logger logger = LoggerFactory.getLogger(MqttBrokerServiceImpl.class);
  @Autowired private MicaRedisCache redisCache;
  @Autowired private MqttServerTemplate server;

  @Override
  public long getOnlineClientSize() {
    Set<String> keySet = redisCache.scan(RedisKeys.CONNECT_STATUS.getKey(StringPool.STAR));
    if (keySet.isEmpty()) {
      return 0L;
    }
    long result = 0;
    for (String redisKey : keySet) {
      Long count = redisCache.getSetOps().size(redisKey);
      if (count != null) {
        result += count;
      }
    }
    return result;
  }

  @Override
  public List<String> getOnlineClients() {
    Set<String> keySet = redisCache.scan(RedisKeys.CONNECT_STATUS.getKey(StringPool.STAR));
    if (keySet.isEmpty()) {
      return Collections.emptyList();
    }
    List<String> clientList = new ArrayList<>();
    for (String redisKey : keySet) {
      Set<String> members = redisCache.sMembers(redisKey);
      if (members != null && !members.isEmpty()) {
        clientList.addAll(members);
      }
    }
    return clientList;
  }

  @Override
  public boolean publish(String topic, String payload) {
    boolean result = server.publishAll(topic, payload.getBytes(StandardCharsets.UTF_8));
    logger.info("Mqtt publishAll result:{};topic:{};payload:{}", result, topic, payload);
    return result;
  }

  @Override
  public boolean closeClientById(String clientId) {
    try{
      server.close(clientId);
    }catch (Exception ex){
      return false;
    }
    return true;
  }


}
