package org.holer.server.timer;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.holer.common.util.HolerUtil;
import org.holer.server.db.DBClientService;
import org.holer.server.db.DBPortService;
import org.holer.server.model.HolerChannel;
import org.holer.server.model.HolerClient;
import org.holer.server.model.HolerPort;
import org.holer.server.util.ServerMgr;
import org.holer.server.util.ServerUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class HolerWorker {
    private static final Logger log = LoggerFactory.getLogger(HolerWorker.class);

    /**
     * 清除过期客户端
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void cleanExpiredData() {
        if (MapUtils.isEmpty(ServerMgr.holerChannels())) {
            log.debug("No holer clients.");
            return;
        }
        long time = 0L;
        HolerClient client = null;

        DBClientService clientService = ServerUtil.getInstance().getClientService();
        DBPortService portService = ServerUtil.getInstance().getPortService();

        List<HolerPort> ports = new ArrayList<HolerPort>();
        List<HolerChannel> hcs = new ArrayList<HolerChannel>(ServerMgr.holerChannels().values());

        for (HolerChannel hc : hcs) {
            client = hc.getClient();
            try {
                if (MapUtils.isEmpty(hc.getPorts())) {

                    ServerMgr.deleteClient(client);
                    clientService.deleteById(client.getClientId());

                    continue;
                }
                ports.clear();
                ports.addAll(hc.getPorts().values());
                for (HolerPort port : ports) {


                    time = System.currentTimeMillis() - port.getExpireAt();
                    if (time >= 864000000L) {

                        ServerMgr.deletePort(port);
                        portService.deleteById(port.getPortId());
                    }
                }

                if (MapUtils.isEmpty(hc.getPorts())) {
                    ServerMgr.deleteClient(client);
                    clientService.deleteById(client.getClientId());
                }
            } catch (Throwable e) {
                log.error("清除过期数据失败。", e);
            }
        }
    }


    /**
     * 关闭客户端
     */
    @Scheduled(initialDelay = 3000L, fixedRate = 120000L)
    public void closeHoler() {
        if (MapUtils.isEmpty(ServerMgr.holerChannels())) {
            log.debug("没有客户端！");
            return;
        }
        HolerClient client = null;
        Collection<HolerChannel> hcs = ServerMgr.holerChannels().values();

        for (HolerChannel hc : hcs) {
            client = hc.getClient();
            if (null == client || MapUtils.isEmpty(hc.getPorts())) {
                continue;
            }

            try {
                if (!client.getEnabled()) {
                    ServerMgr.notify(client.getChannel(), (byte) 8, null);
                    HolerUtil.sleep(3000L);
                    ServerMgr.removeHolerChannel(client.getAccessKey());
                }

                for (HolerPort hp : hc.getPorts().values()) {
                    if (!hp.getEnabled()) {
                        ServerMgr.unbind(hp.getPortNum());
                    }

                    if (hp.getExpireAt() <= System.currentTimeMillis()) {
                        ServerMgr.unbind(hp.getPortNum());
                        log.info(" {}的公共端口  {} 已过期", hp.getPortNum(), client.getName());
                    }

                }
            } catch (Throwable e) {
                log.error("关闭客户端失败 " + client, e);
            }
        }
    }


    @Scheduled(initialDelay = 3000L, fixedRate = 180000L)
    public void setDomain() {
        Collection<HolerChannel> hcs = ServerMgr.holerChannels().values();
        if (CollectionUtils.isEmpty(hcs)) {
            log.debug("没有客户端");
            return;
        }
        File proxyFile = null;
        String proxyName = "";
        for (HolerChannel hc : hcs) {
            if (MapUtils.isEmpty(hc.getPorts())) {
                continue;
            }
            for (HolerPort hp : hc.getPorts().values()) {
                if (StringUtils.isEmpty(hp.getDomain())) {
                    continue;
                }
                proxyName = StringUtils.replace(hp.getDomain(), " ", "-") + "-" + hp.getPortNum() + ".conf";
                proxyFile = new File(ServerMgr.getHolerConfDir() + proxyName);
                if (proxyFile.exists()) {
                    continue;
                }
                ServerMgr.addProxy(hp);
            }
        }
    }
}