package com.ycwl.basic.repository;

import com.ycwl.basic.utils.JacksonUtil;
import com.ycwl.basic.mapper.RenderWorkerMapper;
import com.ycwl.basic.model.pc.renderWorker.entity.RenderWorkerEntity;
import com.ycwl.basic.model.task.req.ClientStatusReqVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class RenderWorkerRepository {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    public static final String RENDER_WORKER_CACHE_KEY = "render_worker:%s";
    public static final String RENDER_WORKER_STATUS_CACHE_KEY = "render_worker:host_status:%s";
    @Autowired
    private RenderWorkerMapper mapper;

    public RenderWorkerEntity getWorkerByAccessKey(String accessKey) {
        String key = String.format(RENDER_WORKER_CACHE_KEY, accessKey);
        if (redisTemplate.hasKey(key)) {
            return JacksonUtil.parseObject(redisTemplate.opsForValue().get(key), RenderWorkerEntity.class);
        }
        RenderWorkerEntity renderWorker = mapper.findByAccessKey(accessKey);
        if (renderWorker != null) {
            redisTemplate.opsForValue().set(key, JacksonUtil.toJSONString(renderWorker), 1, TimeUnit.HOURS);
            redisTemplate.opsForValue().set(String.format(RENDER_WORKER_CACHE_KEY, renderWorker.getId()), JacksonUtil.toJSONString(renderWorker), 1, TimeUnit.HOURS);
        }
        return renderWorker;
    }

    public RenderWorkerEntity getWorker(Long id) {
        String key = String.format(RENDER_WORKER_CACHE_KEY, id);
        if (redisTemplate.hasKey(key)) {
            return JacksonUtil.parseObject(redisTemplate.opsForValue().get(key), RenderWorkerEntity.class);
        }
        RenderWorkerEntity renderWorker = mapper.getById(id);
        if (renderWorker != null) {
            redisTemplate.opsForValue().set(key, JacksonUtil.toJSONString(renderWorker), 1, TimeUnit.HOURS);
            redisTemplate.opsForValue().set(String.format(RENDER_WORKER_CACHE_KEY, renderWorker.getAccessKey()), JacksonUtil.toJSONString(renderWorker), 1, TimeUnit.HOURS);
        }
        return renderWorker;
    }

    public void setWorkerHostStatus(Long id, ClientStatusReqVo status) {
        String key = String.format(RENDER_WORKER_STATUS_CACHE_KEY, id);
        if (status == null) {
            return;
        }
        status.setUpdateAt(new Date());
        RenderWorkerEntity worker = new RenderWorkerEntity();
        worker.setCpuCount(status.getCpu_count());
        worker.setCpuUsage(status.getCpu_usage());
        // 上报的是字节，存储的是兆
        worker.setMemoryAvailable(status.getMemory_available().divide(BigDecimal.valueOf(1024 * 1024), RoundingMode.CEILING));
        worker.setMemoryTotal(status.getMemory_total().divide(BigDecimal.valueOf(1024 * 1024), RoundingMode.CEILING));

        worker.setPlatform(status.getPlatform());
        worker.setRuntimeVersion(status.getRuntime_version());
        worker.setSupportFeature(String.join(",", status.getSupport_feature()));
        worker.setVersion(status.getVersion());
        worker.setUpdateAt(status.getUpdateAt());
        if (!redisTemplate.hasKey(key)) {
            mapper.updateHost(id, worker);
        }
        redisTemplate.opsForValue().set(key, JacksonUtil.toJSONString(status), 1, TimeUnit.HOURS);
    }

    public ClientStatusReqVo getWorkerHostStatus(Long id) {
        String key = String.format(RENDER_WORKER_STATUS_CACHE_KEY, id);
        if (redisTemplate.hasKey(key)) {
            String status = redisTemplate.opsForValue().get(key);
            return JacksonUtil.parseObject(status, ClientStatusReqVo.class);
        }
        return null;
    }

    public void clearCache(Long id) {
        RenderWorkerEntity worker = getWorker(id);
        redisTemplate.delete(String.format(RENDER_WORKER_CACHE_KEY, id));
        if (worker != null) {
            redisTemplate.delete(String.format(RENDER_WORKER_CACHE_KEY, worker.getAccessKey()));
        }
        redisTemplate.delete(String.format(RENDER_WORKER_STATUS_CACHE_KEY, id));
    }
}
